Selectors as variables?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
58 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Selectors as variables?

stefano-franchi
Given Smalltalk's almost infinite reflection capabilities, I assumed it
must be trivial to pass to a method a selector in its calling  
parameters, but I cannot figure out how to do it. Suppose I have a
method like"

fooClass>>doSomething: withThisMethod
anObject withThisMethod


withThisMethod is passed to the the method doSomething as a string and
must be converted to a selector in the method's body. How can I do
that?

Or I may be trying to solve my problem the wrong way. Perhaps the best
way to approach this issue is to pass a block of code instead?


Thanks for the help.

Stefano




__________________________________________________
Stefano Franchi
Department of Philosophy                  Ph:  (64)  9 373-7599 x83940
University Of Auckland Fax: (64) 9 373-8768
Private Bag 92019 [hidden email]
Auckland
New Zealand

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Bruce Badger
On 17/03/07, Stefano Franchi <[hidden email]> wrote:
> Or I may be trying to solve my problem the wrong way. Perhaps the best
> way to approach this issue is to pass a block of code instead?

Yes.  Exactly.

You *can* pass a selector in the form of a Symbol, e.g. #at:put: and
then you can send a message to an object with that selector using
>>perform and variants.  But avoid doing that it you possibly can.
>>perform will make your code harder to refactor and harder to debug.

All the best,
    Bruce
--
Make the most of your skills - with OpenSkills
http://www.openskills.org/

Reply | Threaded
Open this post in threaded view
|

AW: Selectors as variables?

Georg Heeg
In reply to this post by stefano-franchi
Stefano,

The solution is called perform: aSymbol, perform: aSymbol with: anObject,
and perform: aSymbol withArguments: anArray. Be aware the parameter is a
symbol, not a string. To convert a string into a symbol use the message
asSymbol.

Georh

Georg Heeg eK, Dortmund und Köthen, HR Dortmund A 12812
Tel. +49-3496-214328, Fax +49-3496-214712

> -----Ursprüngliche Nachricht-----
> Von: Stefano Franchi [mailto:[hidden email]]
> Gesendet: Sonntag, 18. März 2007 00:50
> An: vwnc
> Cc: Stefano Franchi
> Betreff: Selectors as variables?
>
> Given Smalltalk's almost infinite reflection capabilities, I assumed it
> must be trivial to pass to a method a selector in its calling
> parameters, but I cannot figure out how to do it. Suppose I have a
> method like"
>
> fooClass>>doSomething: withThisMethod
> anObject withThisMethod
>
>
> withThisMethod is passed to the the method doSomething as a string and
> must be converted to a selector in the method's body. How can I do
> that?
>
> Or I may be trying to solve my problem the wrong way. Perhaps the best
> way to approach this issue is to pass a block of code instead?
>
>
> Thanks for the help.
>
> Stefano
>
>
>
>
> __________________________________________________
> Stefano Franchi
> Department of Philosophy                  Ph:  (64)  9 373-7599 x83940
> University Of Auckland Fax: (64) 9 373-8768
> Private Bag 92019 [hidden email]
> Auckland
> New Zealand


Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Samuel S. Shuster <sames@interaccess.com>
In reply to this post by stefano-franchi
Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Boris Popov, DeepCove Labs (SNN)
In reply to this post by stefano-franchi
Re: Selectors as variables?

Technically, yes, but practically one is much better off passing a block instead.

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: [hidden email] <[hidden email]>
To: Stefano Franchi <[hidden email]>
Cc: vwnc <[hidden email]>; Stefano Franchi <[hidden email]>
Sent: Sun Mar 18 10:27:51 2007
Subject: Re: Selectors as variables?

Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?

Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Alexander Ivanov-2
 Re: Selectors as variables?
Passing a block is more powerful but might be more complicated because 'fooClass' would never know in which context a block is going to be performed. In 'perform' case it is always clear that selector will be performed in 'anObject' context.
 
For beginners I would recommend to start exploring 'perform' case and if it is not enough, try to use blocks.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 10:34 AM
To: [hidden email]; [hidden email]
Cc: [hidden email]
Subject: Re: Selectors as variables?

Technically, yes, but practically one is much better off passing a block instead.

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: [hidden email] <[hidden email]>
To: Stefano Franchi <[hidden email]>
Cc: vwnc <[hidden email]>; Stefano Franchi <[hidden email]>
Sent: Sun Mar 18 10:27:51 2007
Subject: Re: Selectors as variables?

Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?

Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Boris Popov, DeepCove Labs (SNN)
Re: Selectors as variables?
Not sure what you mean by context here, could you elaborate?
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
aFoo doSomething: [:v | v inspect]
 
versus,
 
Foo>>doSomething: aSelector
 myInstVar perform: aSelector
 
aFoo doSomething: #inspect
 
Using perform's leads to brittle code as they are not subject to refactorings (method renames, rewrites and such), runtime packager has no way to trace them, code highligter doesn't know what they are etc.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [mailto:[hidden email]]
Sent: Sun 18/03/2007 11:19 AM
To: Boris Popov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Passing a block is more powerful but might be more complicated because 'fooClass' would never know in which context a block is going to be performed. In 'perform' case it is always clear that selector will be performed in 'anObject' context.
 
For beginners I would recommend to start exploring 'perform' case and if it is not enough, try to use blocks.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 10:34 AM
To: [hidden email]; [hidden email]
Cc: [hidden email]
Subject: Re: Selectors as variables?

Technically, yes, but practically one is much better off passing a block instead.

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: [hidden email] <[hidden email]>
To: Stefano Franchi <[hidden email]>
Cc: vwnc <[hidden email]>; Stefano Franchi <[hidden email]>
Sent: Sun Mar 18 10:27:51 2007
Subject: Re: Selectors as variables?

Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?

Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Alexander Ivanov-2
Re: Selectors as variables?
Boris,
 
I meant the general case when block is not specified directly but compiled in other context and then sent by name.
 
OtherFoo>>beforeDoSomething
| block otherObject |
otherObject := 5.
block := [ :v | otherObject  inspect ].
Foo new doSomething: block
 
Then
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
 inspects 5 instead of myInstVar because aBlock was compiled in other context.
That is what I meant. Sorry, I gave a hypothetical example, did not have time to invent a useful one.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 11:30 AM
To: Alexander Ivanov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Not sure what you mean by context here, could you elaborate?
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
aFoo doSomething: [:v | v inspect]
 
versus,
 
Foo>>doSomething: aSelector
 myInstVar perform: aSelector
 
aFoo doSomething: #inspect
 
Using perform's leads to brittle code as they are not subject to refactorings (method renames, rewrites and such), runtime packager has no way to trace them, code highligter doesn't know what they are etc.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [mailto:[hidden email]]
Sent: Sun 18/03/2007 11:19 AM
To: Boris Popov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Passing a block is more powerful but might be more complicated because 'fooClass' would never know in which context a block is going to be performed. In 'perform' case it is always clear that selector will be performed in 'anObject' context.
 
For beginners I would recommend to start exploring 'perform' case and if it is not enough, try to use blocks.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 10:34 AM
To: [hidden email]; [hidden email]
Cc: [hidden email]
Subject: Re: Selectors as variables?

Technically, yes, but practically one is much better off passing a block instead.

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: [hidden email] <[hidden email]>
To: Stefano Franchi <[hidden email]>
Cc: vwnc <[hidden email]>; Stefano Franchi <[hidden email]>
Sent: Sun Mar 18 10:27:51 2007
Subject: Re: Selectors as variables?

Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?

Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Boris Popov, DeepCove Labs (SNN)
Re: Selectors as variables?
Wouldn't such assumption mean that all collection protocols are flawed because you could do,
 
#(1 2 3) do: [:ea | 5 inspect]
 
so one should do,
 
#(1 2 3) do: #inspect
 
There's only so much safety you can have in a language that isn't typed :)
 
Travis with his Symbol>>value: thing aside, not being able to rewrite code is a killer for me,
 
[hidden email] inspect  ->  [hidden email] logToTranscript
 
Either way, its important to know the difference and is ultimately up to a specific problem to pick a specific solution, but I'd be very cautios when recommending perform's over blocks IMHO.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [mailto:[hidden email]]
Sent: Sun 18/03/2007 11:57 AM
To: Boris Popov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Boris,
 
I meant the general case when block is not specified directly but compiled in other context and then sent by name.
 
OtherFoo>>beforeDoSomething
| block otherObject |
otherObject := 5.
block := [ :v | otherObject  inspect ].
Foo new doSomething: block
 
Then
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
 inspects 5 instead of myInstVar because aBlock was compiled in other context.
That is what I meant. Sorry, I gave a hypothetical example, did not have time to invent a useful one.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 11:30 AM
To: Alexander Ivanov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Not sure what you mean by context here, could you elaborate?
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
aFoo doSomething: [:v | v inspect]
 
versus,
 
Foo>>doSomething: aSelector
 myInstVar perform: aSelector
 
aFoo doSomething: #inspect
 
Using perform's leads to brittle code as they are not subject to refactorings (method renames, rewrites and such), runtime packager has no way to trace them, code highligter doesn't know what they are etc.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [mailto:[hidden email]]
Sent: Sun 18/03/2007 11:19 AM
To: Boris Popov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Passing a block is more powerful but might be more complicated because 'fooClass' would never know in which context a block is going to be performed. In 'perform' case it is always clear that selector will be performed in 'anObject' context.
 
For beginners I would recommend to start exploring 'perform' case and if it is not enough, try to use blocks.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 10:34 AM
To: [hidden email]; [hidden email]
Cc: [hidden email]
Subject: Re: Selectors as variables?

Technically, yes, but practically one is much better off passing a block instead.

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: [hidden email] <[hidden email]>
To: Stefano Franchi <[hidden email]>
Cc: vwnc <[hidden email]>; Stefano Franchi <[hidden email]>
Sent: Sun Mar 18 10:27:51 2007
Subject: Re: Selectors as variables?

Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?

Reply | Threaded
Open this post in threaded view
|

Fwd: Selectors as variables?

Bruce Badger
In reply to this post by Alexander Ivanov-2
On 18/03/07, Alexander Ivanov <[hidden email]> wrote:
> Passing a block is more powerful but might be more complicated because
> 'fooClass' would never know in which context a block is going to be
> performed. In 'perform' case it is always clear that selector will be
> performed in 'anObject' context.
>
> For beginners I would recommend to start exploring 'perform' case and if it
> is not enough, try to use blocks.

Alexander, I do not agree at all.  Sorry :-/

Using perform is a bad habit and it is one it can be a hard to get out of.

I also disagree with your analysis.  Using blocks retains far more
contextual information than using perform.  You may see where the
perform happens in the debugger but figuring out where the symbol came
from is much harder.

I have heard many times over the years that, "well this is a special
tricky case and we really just have to use perform".  I have yet to
see a sitation where a blocks based solution was not clearer and
easier to maintain.

Really, if you can, stick with using blocks.

Um, IMO.

Very best regards,
    Bruce
--
Make the most of your skills - with OpenSkills
http://www.openskills.org/

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Steve Aldred
In reply to this post by Alexander Ivanov-2
Alexander Ivanov wrote:
Re: Selectors as variables?
 
OtherFoo>>beforeDoSomething
| block otherObject |
otherObject := 5.
block := [ :v | otherObject  inspect ].
Foo new doSomething: block
 
Then
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
 inspects 5 instead of myInstVar because aBlock was compiled in other context.
That is what I meant. Sorry, I gave a hypothetical example, did not have time to invent a useful one.
If you want the block to do things with the argument, which is the whole point of the exercise, then you write block code that does just that. For the above the block should then be:

    [:v | v inspect]

then there is no confusion over what is being acted on. Of course any self references in the block refer to where the block was compiled not where it is executed - which does confuse newbies.

cheers
Steve A
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [[hidden email]]
Sent: Sunday, March 18, 2007 11:30 AM
To: Alexander Ivanov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Not sure what you mean by context here, could you elaborate?
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
aFoo doSomething: [:v | v inspect]
 
versus,
 
Foo>>doSomething: aSelector
 myInstVar perform: aSelector
 
aFoo doSomething: #inspect
 
Using perform's leads to brittle code as they are not subject to refactorings (method renames, rewrites and such), runtime packager has no way to trace them, code highligter doesn't know what they are etc.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [[hidden email]]
Sent: Sun 18/03/2007 11:19 AM
To: Boris Popov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Passing a block is more powerful but might be more complicated because 'fooClass' would never know in which context a block is going to be performed. In 'perform' case it is always clear that selector will be performed in 'anObject' context.
 
For beginners I would recommend to start exploring 'perform' case and if it is not enough, try to use blocks.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [[hidden email]]
Sent: Sunday, March 18, 2007 10:34 AM
To: [hidden email]; [hidden email]
Cc: [hidden email]
Subject: Re: Selectors as variables?

Technically, yes, but practically one is much better off passing a block instead.

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: [hidden email] [hidden email]
To: Stefano Franchi [hidden email]
Cc: vwnc [hidden email]; Stefano Franchi [hidden email]
Sent: Sun Mar 18 10:27:51 2007
Subject: Re: Selectors as variables?

Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?


Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Alexander Ivanov-2
Re: Selectors as variables?
It is hard to say what would be more confusing for newbies, blocks or 'perform'. From my point of view both are not quite easy for non-smalltalkers:
 
 [:v | v inspect] value: anObject 
or
anObject perform: #inspect
Yes, perform is bad in debugging but blocks are less convenient if we go a little bit further.
 
How do you implement this:
 
Foo>>doSeveralActions: actions
    actions do: [ :selector | anObject perform: selector]
 
Foo new doSeveralActions: #(read write save print)
 
Definition is OK:
 
Foo>>doSeveralActions: actions
    actions do: [ :block | block value: anObject ].
 
But what about call?
 
blocks := OrderedCollection new
    add: [ :v | v read ];
    add: [ :v | v write ];
    add: [ :v | v save ];
    add: [ :v | v print];
    yourself.
Foo new doSeveralActions: blocks.
 
If somebody find something less ugly, I will switch to blocks too.
 
Regards,
 
Alex

Alex Ivanov
[hidden email]
778 898-2527


 
 
 
 
 -----Original Message-----
From: Steve Aldred [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 8:22 PM
To: vwnc
Subject: Re: Selectors as variables?

Alexander Ivanov wrote:
 
OtherFoo>>beforeDoSomething
| block otherObject |
otherObject := 5.
block := [ :v | otherObject  inspect ].
Foo new doSomething: block
 
Then
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
 inspects 5 instead of myInstVar because aBlock was compiled in other context.
That is what I meant. Sorry, I gave a hypothetical example, did not have time to invent a useful one.
If you want the block to do things with the argument, which is the whole point of the exercise, then you write block code that does just that. For the above the block should then be:

    [:v | v inspect]

then there is no confusion over what is being acted on. Of course any self references in the block refer to where the block was compiled not where it is executed - which does confuse newbies.

cheers
Steve A
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [[hidden email]]
Sent: Sunday, March 18, 2007 11:30 AM
To: Alexander Ivanov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Not sure what you mean by context here, could you elaborate?
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
aFoo doSomething: [:v | v inspect]
 
versus,
 
Foo>>doSomething: aSelector
 myInstVar perform: aSelector
 
aFoo doSomething: #inspect
 
Using perform's leads to brittle code as they are not subject to refactorings (method renames, rewrites and such), runtime packager has no way to trace them, code highligter doesn't know what they are etc.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [[hidden email]]
Sent: Sun 18/03/2007 11:19 AM
To: Boris Popov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Passing a block is more powerful but might be more complicated because 'fooClass' would never know in which context a block is going to be performed. In 'perform' case it is always clear that selector will be performed in 'anObject' context.
 
For beginners I would recommend to start exploring 'perform' case and if it is not enough, try to use blocks.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [[hidden email]]
Sent: Sunday, March 18, 2007 10:34 AM
To: [hidden email]; [hidden email]
Cc: [hidden email]
Subject: Re: Selectors as variables?

Technically, yes, but practically one is much better off passing a block instead.

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: [hidden email] [hidden email]
To: Stefano Franchi [hidden email]
Cc: vwnc [hidden email]; Stefano Franchi [hidden email]
Sent: Sun Mar 18 10:27:51 2007
Subject: Re: Selectors as variables?

Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?


Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Boris Popov, DeepCove Labs (SNN)
Re: Selectors as variables?
Oh, but examples do matter. This specific case becomes,
 
anObject read; write; save; print
 
It all comes down to code readability and maintainability (my pet peeve with selectors). (Arrays of) selectors do have their place, but its over at http://c2.com/xp/CodeSmell.html IMHO, because one sacrifices way more than one gains. I'd hate to do a method rename and leave out all the tricky places where #print wasn't an actual method send. I've spent way too much time around code that synthesized selectors to do #perform's later, imagine (self perform: 'get' , aVariableName) and multiply that by 1,000 to scratch the surface of the kinds of problems that results in. There's enough tricky problems in today's software that occupy our precious brain cycles to introduce solutions that are known uncertainty magnets. Just my .02c, I'm open to better examples to earn my support.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [mailto:[hidden email]]
Sent: Sun 18/03/2007 9:36 PM
To: Steve Aldred; vwnc
Subject: RE: Selectors as variables?

It is hard to say what would be more confusing for newbies, blocks or 'perform'. From my point of view both are not quite easy for non-smalltalkers:
 
 [:v | v inspect] value: anObject 
or
anObject perform: #inspect
Yes, perform is bad in debugging but blocks are less convenient if we go a little bit further.
 
How do you implement this:
 
Foo>>doSeveralActions: actions
    actions do: [ :selector | anObject perform: selector]
 
Foo new doSeveralActions: #(read write save print)
 
Definition is OK:
 
Foo>>doSeveralActions: actions
    actions do: [ :block | block value: anObject ].
 
But what about call?
 
blocks := OrderedCollection new
    add: [ :v | v read ];
    add: [ :v | v write ];
    add: [ :v | v save ];
    add: [ :v | v print];
    yourself.
Foo new doSeveralActions: blocks.
 
If somebody find something less ugly, I will switch to blocks too.
 
Regards,
 
Alex

Alex Ivanov
[hidden email]
778 898-2527


 
 
 
 
 -----Original Message-----
From: Steve Aldred [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 8:22 PM
To: vwnc
Subject: Re: Selectors as variables?

Alexander Ivanov wrote:
 
OtherFoo>>beforeDoSomething
| block otherObject |
otherObject := 5.
block := [ :v | otherObject  inspect ].
Foo new doSomething: block
 
Then
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
 inspects 5 instead of myInstVar because aBlock was compiled in other context.
That is what I meant. Sorry, I gave a hypothetical example, did not have time to invent a useful one.
If you want the block to do things with the argument, which is the whole point of the exercise, then you write block code that does just that. For the above the block should then be:

    [:v | v inspect]

then there is no confusion over what is being acted on. Of course any self references in the block refer to where the block was compiled not where it is executed - which does confuse newbies.

cheers
Steve A
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [[hidden email]]
Sent: Sunday, March 18, 2007 11:30 AM
To: Alexander Ivanov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Not sure what you mean by context here, could you elaborate?
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
aFoo doSomething: [:v | v inspect]
 
versus,
 
Foo>>doSomething: aSelector
 myInstVar perform: aSelector
 
aFoo doSomething: #inspect
 
Using perform's leads to brittle code as they are not subject to refactorings (method renames, rewrites and such), runtime packager has no way to trace them, code highligter doesn't know what they are etc.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [[hidden email]]
Sent: Sun 18/03/2007 11:19 AM
To: Boris Popov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Passing a block is more powerful but might be more complicated because 'fooClass' would never know in which context a block is going to be performed. In 'perform' case it is always clear that selector will be performed in 'anObject' context.
 
For beginners I would recommend to start exploring 'perform' case and if it is not enough, try to use blocks.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [[hidden email]]
Sent: Sunday, March 18, 2007 10:34 AM
To: [hidden email]; [hidden email]
Cc: [hidden email]
Subject: Re: Selectors as variables?

Technically, yes, but practically one is much better off passing a block instead.

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: [hidden email] [hidden email]
To: Stefano Franchi [hidden email]
Cc: vwnc [hidden email]; Stefano Franchi [hidden email]
Sent: Sun Mar 18 10:27:51 2007
Subject: Re: Selectors as variables?

Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?


Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Alexander Ivanov-2
Re: Selectors as variables?
"This specific case becomes,
 
anObject read; write; save; print."...
 
And then we are renaming method 'doSomething' to 'doReadWriteSavePrint' :-). The problem is Foo does not know this list at compile time.
 
As for maintenance, I agree with you. Perform is bad guy.
 
Alex

 -----Original Message-----
From: Boris Popov [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 9:54 PM
To: Alexander Ivanov; Steve Aldred; vwnc
Subject: RE: Selectors as variables?

Oh, but examples do matter. This specific case becomes,
 
anObject read; write; save; print
 
It all comes down to code readability and maintainability (my pet peeve with selectors). (Arrays of) selectors do have their place, but its over at http://c2.com/xp/CodeSmell.html IMHO, because one sacrifices way more than one gains. I'd hate to do a method rename and leave out all the tricky places where #print wasn't an actual method send. I've spent way too much time around code that synthesized selectors to do #perform's later, imagine (self perform: 'get' , aVariableName) and multiply that by 1,000 to scratch the surface of the kinds of problems that results in. There's enough tricky problems in today's software that occupy our precious brain cycles to introduce solutions that are known uncertainty magnets. Just my .02c, I'm open to better examples to earn my support.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [mailto:[hidden email]]
Sent: Sun 18/03/2007 9:36 PM
To: Steve Aldred; vwnc
Subject: RE: Selectors as variables?

It is hard to say what would be more confusing for newbies, blocks or 'perform'. From my point of view both are not quite easy for non-smalltalkers:
 
 [:v | v inspect] value: anObject 
or
anObject perform: #inspect
Yes, perform is bad in debugging but blocks are less convenient if we go a little bit further.
 
How do you implement this:
 
Foo>>doSeveralActions: actions
    actions do: [ :selector | anObject perform: selector]
 
Foo new doSeveralActions: #(read write save print)
 
Definition is OK:
 
Foo>>doSeveralActions: actions
    actions do: [ :block | block value: anObject ].
 
But what about call?
 
blocks := OrderedCollection new
    add: [ :v | v read ];
    add: [ :v | v write ];
    add: [ :v | v save ];
    add: [ :v | v print];
    yourself.
Foo new doSeveralActions: blocks.
 
If somebody find something less ugly, I will switch to blocks too.
 
Regards,
 
Alex

Alex Ivanov
[hidden email]
778 898-2527


 
 
 
 
 -----Original Message-----
From: Steve Aldred [mailto:[hidden email]]
Sent: Sunday, March 18, 2007 8:22 PM
To: vwnc
Subject: Re: Selectors as variables?

Alexander Ivanov wrote:
 
OtherFoo>>beforeDoSomething
| block otherObject |
otherObject := 5.
block := [ :v | otherObject  inspect ].
Foo new doSomething: block
 
Then
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
 inspects 5 instead of myInstVar because aBlock was compiled in other context.
That is what I meant. Sorry, I gave a hypothetical example, did not have time to invent a useful one.
If you want the block to do things with the argument, which is the whole point of the exercise, then you write block code that does just that. For the above the block should then be:

    [:v | v inspect]

then there is no confusion over what is being acted on. Of course any self references in the block refer to where the block was compiled not where it is executed - which does confuse newbies.

cheers
Steve A
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [[hidden email]]
Sent: Sunday, March 18, 2007 11:30 AM
To: Alexander Ivanov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Not sure what you mean by context here, could you elaborate?
 
Foo>>doSomething: aBlock
 aBlock value: myInstVar
 
aFoo doSomething: [:v | v inspect]
 
versus,
 
Foo>>doSomething: aSelector
 myInstVar perform: aSelector
 
aFoo doSomething: #inspect
 
Using perform's leads to brittle code as they are not subject to refactorings (method renames, rewrites and such), runtime packager has no way to trace them, code highligter doesn't know what they are etc.
 
Cheers!
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Alexander Ivanov [[hidden email]]
Sent: Sun 18/03/2007 11:19 AM
To: Boris Popov; [hidden email]; [hidden email]
Cc: [hidden email]
Subject: RE: Selectors as variables?

Passing a block is more powerful but might be more complicated because 'fooClass' would never know in which context a block is going to be performed. In 'perform' case it is always clear that selector will be performed in 'anObject' context.
 
For beginners I would recommend to start exploring 'perform' case and if it is not enough, try to use blocks.
 
Regards,
 
Alex
 
 
-----Original Message-----
From: Boris Popov [[hidden email]]
Sent: Sunday, March 18, 2007 10:34 AM
To: [hidden email]; [hidden email]
Cc: [hidden email]
Subject: Re: Selectors as variables?

Technically, yes, but practically one is much better off passing a block instead.

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: [hidden email] [hidden email]
To: Stefano Franchi [hidden email]
Cc: vwnc [hidden email]; Stefano Franchi [hidden email]
Sent: Sun Mar 18 10:27:51 2007
Subject: Re: Selectors as variables?

Stefano

>fooClass>>doSomething: withThisMethod
>anObject withThisMethod

If you pass in the selector, then:

doSomething: aSymbol
        anObject perform: aSymbol

                                And So It Goes
                                     Sames
______________________________________________________________________

Samuel S. Shuster [|]
VisualWorks Engineering, GUI Project
Smalltalk Enables Success -- What Are YOU Using?


Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Reinout Heeck-2
In reply to this post by Alexander Ivanov-2

> Definition is OK:
>  
> Foo>>doSeveralActions: actions
>     actions do: [ :block | block value: anObject ].
>  
> But what about call?
>  
> blocks := OrderedCollection new
>     add: [ :v | v read ];
>     add: [ :v | v write ];
>     add: [ :v | v save ];
>     add: [ :v | v print];
>     yourself.
> Foo new doSeveralActions: blocks.
>  
> If somebody find something less ugly, I will switch to blocks too.
Trivial:
  implement #, on BlockClosure.

Foo new
  doSeveralActions: [ :v | v read ], [ :v | v write ], [ :v | v save ],
[ :v | v print].



One of my gripes with Smalltalk is that block syntax is not considered
to be a literal, I would love to be able to write stuff like:

actions := #( [ :v | v read ] [ :v | v write ] [ :v | v save ] [ :v | v
print] ).

R
-

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Charles A. Monteiro-2
Reinout:

Just tried it while finishing my morning scone and Starbucks triple shot  
grande latte. In anycase you can achieve what you want by using  
BraceContructors.

If using BraceContructors it should go as follows:

actions := { [ :v | v read ]. [ :v | v write ]. [ :v | v save ]. [ :v | v  
print]. }

I find the syntax quite reasonable. I must admit to using  
BraceConstructors quite a bit.

hth :)

-Charles




On Mon, 19 Mar 2007 04:19:27 -0500, Reinout Heeck <[hidden email]>  
wrote:

>
>> Definition is OK:
>>  Foo>>doSeveralActions: actions
>>     actions do: [ :block | block value: anObject ].
>>  But what about call?
>>  blocks := OrderedCollection new
>>     add: [ :v | v read ];
>>     add: [ :v | v write ];
>>     add: [ :v | v save ];
>>     add: [ :v | v print];
>>     yourself.
>> Foo new doSeveralActions: blocks.
>>  If somebody find something less ugly, I will switch to blocks too.
> Trivial:
>   implement #, on BlockClosure.
>
> Foo new
>   doSeveralActions: [ :v | v read ], [ :v | v write ], [ :v | v save ],  
> [ :v | v print].
>
>
>
> One of my gripes with Smalltalk is that block syntax is not considered  
> to be a literal, I would love to be able to write stuff like:
>
> actions := #( [ :v | v read ] [ :v | v write ] [ :v | v save ] [ :v | v  
> print] ).
>
> R
> -



--
Charles A. Monteiro
http://wiki.nycsmalltalk.org
http://www.monteirosfusion.com
http://monteirofusion.blogspot.com

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Travis Griggs-3
In reply to this post by Reinout Heeck-2
On Mar 19, 2007, at 2:19, Reinout Heeck wrote:


Definition is OK:
 Foo>>doSeveralActions: actions
    actions do: [ :block | block value: anObject ].
 But what about call?
 blocks := OrderedCollection new
    add: [ :v | v read ];
    add: [ :v | v write ];
    add: [ :v | v save ];
    add: [ :v | v print];
    yourself.
Foo new doSeveralActions: blocks.
 If somebody find something less ugly, I will switch to blocks too.
Trivial:
 implement #, on BlockClosure.

Foo new
 doSeveralActions: [ :v | v read ], [ :v | v write ], [ :v | v save ], [ :v | v print].

Hmm....

I think if I were doing this, I'd be more inclined to implement:

BlockClosure>>, aBlockClosure
"Return a new block which will evaluate the receiver and then the argument in order"
^[self value. aBlockClosureValue]

Just because, I don't know, it seems cool to make them recursive structures using themselves and be able to have it be uniform (i.e. the API remains value).

--
Travis Griggs
Objologist
"There are a thousand hacking at the branches of evil to one who is striking at the root" - Henry David Thoreau


Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Travis Griggs-3
In reply to this post by stefano-franchi
On Mar 17, 2007, at 16:50, Stefano Franchi wrote:

Given Smalltalk's almost infinite reflection capabilities, I assumed it must be trivial to pass to a method a selector in its calling  parameters, but I cannot figure out how to do it. Suppose I have a method like"

fooClass>>doSomething: withThisMethod
anObject withThisMethod


withThisMethod is passed to the the method doSomething as a string and must be converted to a selector in the method's body. How can I do that?

Or I may be trying to solve my problem the wrong way. Perhaps the best way to approach this issue is to pass a block of code instead?

Stefano,

I see you got your answers eventually (perform: and variants). And I hope that the discussion that followed about not confusing a beginner was not too confusing. I know it was for me.

Both techniques have their place. With much cross over. They are both used _extensively_ throughout the system itself, so I think that neither can be all that bad. Without knowing what more of your code is trying to solve, it would probably be wrong of us to try and really steer you to use one technique or the other.

The cool thing about Smalltalk is that it is so open to explore what solution is best for you, to refine your own guidelines as you go.

--
Travis Griggs
Objologist
One man's blue plane is another man's pink plane.


Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Bruce Badger
On 19/03/07, Travis Griggs <[hidden email]> wrote:
> Both techniques have their place. With much cross over. They are both used
> _extensively_ throughout the system itself, so I think that neither can be
> all that bad.

Really?  Can you point to an example in the base VisualWorks system
where, in your view, it was more appropriate to use a perform than use
a block?

All the best,
    Bruce
--
Make the most of your skills - with OpenSkills
http://www.openskills.org/

Reply | Threaded
Open this post in threaded view
|

AW: Selectors as variables?

Georg Heeg
Bruce,

The most predominant examples are in the UI. Most actions in menu
specifications are symbols as well as aspects. They all are sent by perform:

Georg

Georg Heeg eK, Dortmund und Köthen, HR Dortmund A 12812
Tel. +49-3496-214328, Fax +49-3496-214712

> -----Ursprüngliche Nachricht-----
> Von: Bruce Badger [mailto:[hidden email]]
> Gesendet: Montag, 19. März 2007 16:34
> An: Travis Griggs
> Cc: vwnc
> Betreff: Re: Selectors as variables?
>
> On 19/03/07, Travis Griggs <[hidden email]> wrote:
> > Both techniques have their place. With much cross over. They are both
> used
> > _extensively_ throughout the system itself, so I think that neither can
> be
> > all that bad.
>
> Really?  Can you point to an example in the base VisualWorks system
> where, in your view, it was more appropriate to use a perform than use
> a block?
>
> All the best,
>     Bruce
> --
> Make the most of your skills - with OpenSkills
> http://www.openskills.org/


123