This file contains snippets of code that can be useful sometimes.
- Download a file with a progress bar
- Bench and profile a project from the tests
- Automatic transformation of Pharo's methods source code
- Browse all available icons
- Rename programatically methods
- Get all senders/implementors of a selector
- Find dependencies on a package
| outputFileName url |
outputFileName := './pharoLogo.png'.
outputFileName asFileReference ensureDelete.
url := 'http://files.pharo.org/media/logo/logo-flat.png' asZnUrl.
[ :bar |
bar title: 'Download: ' , url asString , ' to ' , outputFileName.
[ ZnClient new
url: url;
signalProgress: true;
downloadTo: outputFileName ]
on: HTTPProgress
do: [ :progress |
progress isEmpty ifFalse: [ bar current: progress percentage ].
progress resume ] ] asJob run
packageSelectionBlock := [ :e | e name beginsWith: 'Spec' ].
testSuite := TestSuite new.
((RPackageOrganizer default packages select: packageSelectionBlock) flatCollect: #classes) select: [ :e | e inheritsFrom: TestCase ] thenDo: [ :e | e addToSuiteFromSelectors: testSuite ].
"Bench the test suite"
[ testSuite run ] bench.
"Profile the test suite"
TimeProfiler spyOn: [ testSuite run ]
During software maintenance, being able to transform automatically source code can be handy. It can be done easily in Pharo using the built-in code rewriting engine.
For example, let's say that we want to replace the occurences of #symbolToReplace
symbol with occurences of #replacedSymbol
in the following method:
ExampleCodeTransformation>>#methodToTransform
1 + 1 = 2
ifTrue: [ ^ #symbolToReplace ].
^ #symbolToReplace , #symbolNotToReplace
It can be done easily using the following code snippet:
compiledMethod := ExampleCodeTransformation >> #methodToTransform.
ast := compiledMethod parseTree.
"Here we select only nodes holding the target symbol and we replace it with a node representing `#replacedSymbol`."
ast allChildren
select: [ :n | n class = RBLiteralValueNode and: [ n value = #symbolToReplace ] ]
thenDo: [ :node |
rewriter := RBParseTreeRewriter new
replaceTree: node
withTree: (RBLiteralValueNode value: #replacedSymbol);
yourself.
(rewriter executeTree: ast)
ifTrue: [ node replaceWith: rewriter tree ] ].
"Serialize the new AST as Pharo source code."
rewrittenSourceCode := (BIConfigurableFormatter format: ast).
"Recompile the method with transformed source code."
ExampleCodeTransformation compile: rewrittenSourceCode
The following code snippet opens an inspector in which the 'Icons' tab allows to browse all icons available in the image.
Smalltalk ui icons inspect
To get a specific icon, use #iconNamed:
method as follow:
Smalltalk ui icons iconNamed: #arrowUp
In this section we'll present a snippet of code to rename all the methods of a class containing a substring to replace it by another substring.
"Class in which we want to rename the methods"
class := EpApplyPreviewerTest.
"Substring to replace"
from := 'With'.
"Substring to use"
to := 'Without'.
class methods
select: [ :method | method selector includesSubstring: from ]
thenDo: [ :method |
| permutationMap |
"We want to keep the arguments in the same order"
permutationMap := method numArgs = 0 ifTrue: [ #() ] ifFalse: [ (1 to: method numArgs) asArray ].
(RBRenameMethodRefactoring
renameMethod: method selector
in: class
to: (method selector copyReplaceAll: from with: to)
permutation: permutationMap) execute ]
Be careful, this will also rename the senders of those methods and if you have two methods of the same name in the image, it might badly rename some. Use this only on methods with unique names.
The selector of a method is kind of the equivalent of the signature of a method or function in other programming language.
However, since Pharo is dynamically typed, this selector is only the name of the method, without the parameters.
For example, the selector of the method below is #name:
Example>>name: aString
name := aString
For a given CompiledMethod
in the system, its selector is accessible via #selector
message.
(Object>>#yourself) selector. "#yourself"
To get all the senders of a selector accross the image, simply call #senders
on the selector:
#yourself senders
To get all CompiledMethod
s implementing a method having a selector, simply call #implementors
on the selector:
#yourself implementors
In Pharo it is easy to find the dependencies of one package through the Dependency Analyzer
, but there is not tool to browse the dependencies on a single package.
It is possible to do it programatically via this snippet:
report := DADependencyChecker new computeImageDependencies. "This might take some time but it will run in background"
report knownDependantsOf: 'Epicea' "Replace Epicia by the name of your package."