Searching in Flamel!

I want to show a proposal for using the matching expression builder.

The idea is to keep it simple, so if you think this is very complex, let me know!

First of all open Flamel-UI, in a workspace:

Flamel new openWithSpec.

For those non familiarized with the project, you will see something like this:

Flamel - UI
A short summary:

  • Scope for the rule: Here we restrict the scopes for the rule, for those familiarized with the RW-Engine behind this we have the RBEnvironment objects.
  • Define match: The idea here is to help to define the matching rule, for this we have:
  • Starting point example method: We choose a method to use as an example for the pattern, you can change for the method you want, and you have more options available (just, right click and see)
  • Pattern expression type: 3 options here:
  •             Method: The pattern corresponds to a method
  •             Expression: The pattern corresponds to an expression, so we don’t have the selector definition plus the optional temporary variables definition
  •             Both: Basically, try to search the matching expression as a method and as an expression
  • Matching expression: The pattern we will search
  • Define transformation: The same idea for the matching but in this case to help you with the transformation

How to use Flamel in 5 stepChoose the scope for your rule

  1. if we don’t clarify this we will look in the hole image and this takes time

  2. Select your base example: You can use the default example or… choose an example method that is better for you

    The example will help you to define the pattern

    For change the example, right click in the Starting point example method and choose: “Change example”, you will see a window like this:

    FlamelUI-selectMethodWhere you can choose the class and method you desire to use as an example.

  3. Choose the Pattern expression type: If you are not sure, just let the both and we will try to do our best, but if you really know if you want to define a pattern with a method syntax or not (an expression) choose the best option.
  4. Define the matching expression: For this we use the right-click menu options to help us.
    We can start choosing “Reset expression” and then we will see the same code in the example as a pattern
    Then we use the menu to modify the expression
  5.  Perform the search just clicking in the Search button.

And then see your results!

Advertisements

Just want to match!

My face inspecting the empty result set

My face inspecting the empty result set

It took me many hours (and too much coffee) to realized all of this and I want to share with you some tips to help you define the matching pattern you really want to aplly

  • Pay attention to the dots! `sel “@.Statements1. self subclassResponsibility.  “@.Statements2 is very different to: `sel “@.Statements1 self subclassResponsibility.  “@.Statements2
  • Matching the selectors is not a simple task
  • Is not the same matching an expression that matching a method one line can change everything!

If you say:

</pre>
matcher <strong>matchesMethod:</strong> aMatchingExpression

You are particullary saying that aMatchingExpression should be parsed doing: RBParser parseRewriteMethod: aMatchingExpression instead of RBParser parseRewriteExpression: aMatchingExpression

And this mean that:

  1. Your string is well formed, if you have a syntactic error you will see the window saying that the expression is not correct
  2. Your string has a method structure
  3. Your metavariables will play as a message send or as a variable depending on the context

A fast example, imagine this expression:

`anObject size.

Let’s play we are the a cool parser and someone told us hey… this is a string, but you should interpret it as a mehod… so:

`anObject = the selector so I want all the unary methods

size = a variable named ‘size’ because it can’t be a parameter because my message is unary, it’s not a variable definition it has to be a variable.

So as a cool parser I say that I will match with all the unary methods that the body is just an unique sentence that contains a variable called ‘size’

Now, imagine someone told us this is an expression… so:
`anObject = the object, I do not know nothing, only that here goes an unique object
size = before I had an object so here I should have an invocation for the message #size.

So as a cool parser I say that I will match with all the methods the expressions that sends the message size

  • If you look for a particular message send you should care about the structure:
  1. Do you want all the senders? for defining the expresion is not the same object messageToFind that object message anotherMessage messageToFind moreMessages
  2. It can be inside a block?
  3. It can be invoked as a symbol? object perform: #messageTofind
  4. It can be in any part of method? (the first sentence? after that can be more message sends?)
  • The matcher uses pattern matching! You give an alias and when it matches then is bounded and that’s

This pattern:

`sel “@.Statements1. self messageTofind.  “@.Statements1

Does not match with:

example
self oneMessage.
self messageTofind.
self otherMessage.

Because we use the same variable name! Statements1 and in the matching it bounded to the statement self oneMessage that is NOT identical to self otherMessage so we don’t have the match.
But! It should match with:

example
self oneMessage.
self messageTofind.
self oneMessage.

But this feature is really cool if you want to search repeated code in the same method…

  • If you are matching inside a method, does the method defines temporary variables?
  • Remember that when you parse if the variable definition is wmpty it get’s ignored but if you do not put it in your pattern and the method defines a temp you are excluding it.

An example

example
|aTempVar|
self messageTofind.

matches with method pattern:

`sel |`@vars| `object messageTofind

but does NOT match with:

`sel `object messageTofind 

In the end I can understand that all this “tinny” details are very important… but if you want to match a common case it can be really ugly and it’s VERY easy to do it wrong.

But do not worry too much one big goal for Flamel it’s to offer a simple API to avoid all this commons errors.

Developing under develop

I think that this had happend to a lot of smalltalkers with the time… After a while you just get used to do some tasks that aren’t very intuitive for a newcommer and started to feel “natural”. Yes… the classic user that get used to a system…

And these days I’ve been watching the frustation of someone that is starting the path and trying to help I just realize that I have a lot of tips and tricks that I follow unconcious and decided to make an entry here maybe this help and more people with more expirience would share their tips.

Starting

Before start your coding you have to setup your environment, an one choose is which image? Wich version? I strongly suggest the lastest but maybe you should keep reading before choose.

Why does the title say developing under develop?

Because when I start a new project in pharo I want to use the lastest features, Pharo is getting really cool and has improved a lot and to use all those feautures I need the lastest image.

Other reason is that while you are programming your system you are testing Pharo also and time to time you find some problems and correct them are not so hard, so it pushes you to improve Pharo itself!

So in order to have all the benefits you have to use the lastest image (under develop) and with that you should have concience in the consecuencies and take some considerations.

Mental preparation

Ok you are in a system under developing, IS NOT PERFECT but it is in the path to be one step near to the perfection and to achive that needs your help.  Basically applies to the system the same rule that applies to your development:

  • The system may change: some apis can change and maybe you are an user of that API. This is not bad! Probably it’s a refactor to improve the code, so you get benefit because your code will be more expressive.
  • The system can have bugs! Yes as I said is not perfect and it’s not on purpose.
  • Sometimes the lastest image have problems, yes we would love to be perfect but sometimes there are some nusty side effects and some functionality that stop working, but to find it sometimes you have to release and wait for feedback and you are a great candidate to give that feedback.
  • The debugger does not mean that everything is lost, your first approach sholud NOT be close the debuger and say abandom abandom!
  • Get attach to an image is not a great idea… Your “lastest” image is not there for stay with you for a long time, you have chossen to use under develop image, this means that your image will change (in the happiness path but change anyway) and deliberated decide to attach with an old particular version from a changing image has the worst of two worlds: Now you are not in an stable but you are stuck in a version that nobody is using and by consecuence you don’t have the new fratures/fixes
  • The tests are your friends 🙂 (As usual!)

Tips and tricks!

If you are new at Pharo y strongly recomend to take a look in Mariano Peck‘s blog particullary the post called: Pharo tips and tricks. The shortcuts are really cool and from your previous experience maybe you would say… I can’t do that only with my keyboard… but the true is that probably you can do it! Just take a look in Key mappings

Mitigate the errors

Some tips when you are developing:

  • Use fresh images, if you are in lastest Pharo a week with the same image is really A LOT
  • Allways use a repository to share your code, I strongly recommend smalltalkhub
  • If your project has a complex setup invest some time making a configuration
  • Do not make a lot of actions before commit, small and numerous commit is too much easier than one big commit
  • Reverting the changes is not so easy. There are a lot of effor in this topic and is comming, but is not ready! So, try to keep it simple
  • If you find extrange behavior send email to the user mailing list: pharo-users@lists.pharo.org nobody will judge you for asking!
  • Lenguage barrier is not so hard with a tolerating comunity, Pharo comunity is full of non native-english speaker and is more important to improve Pharo than writing poetry, just ask and try to make that understandable (look… if I’m writing this blog with my horrible english, you shouldn’t care at all)
  • If you can reproduce a problem open an issue in the issue tracker
  • Save your image regulary, if you have worked for a while and you have uncommited changes save your image regulary!
  • Before killing your image because “does not respond” you have the resource to interrupt the process just press alt + ‘.’ or cmd + ‘.’
  • Contribute and give feedback, it’s a way to keep growing

I’m sure we have a lot more, but at least is a beginning!