Mantis - Squeak
Viewing Issue Advanced Details
5319 Kernel feature always 10-29-06 03:36 01-22-08 05:31
new 3.9  
0005319: Please add #askFor: to Object
Very useful function

#askFor: selector

^(self respondsTo: selector) ifTrue: [ self selector ] ifFalse: [ false ] [^] (257 bytes) 10-29-06 03:37 [^] (260 bytes) 10-31-06 04:12 [^] (243 bytes) 10-31-06 13:32 [^] (352 bytes) 10-31-06 14:17 [^] (283 bytes) 12-18-06 12:24 [^] (406 bytes) 12-18-06 12:24
 Object-askForTests.1.cs [^] (1,446 bytes) 01-06-07 06:02 [^] (443 bytes) 01-06-07 06:02 [^] (343 bytes) 01-06-07 06:03 [^] (343 bytes) 01-09-07 09:22 [^] (337 bytes) 01-09-07 09:26
 Object-askForTests.2.cs [^] (848 bytes) 01-09-07 09:29
 AskFor.1.cs [^] (1,497 bytes) 01-21-08 22:31

10-30-06 06:53   
As written I don't think this will work as intended.

There is name confusion here.

as uploaded it reads:

'From Squeak3.9gamma of ''23 July 2006'' [latest update: 0007066] on 29 October 2006 at 1:24:44 am'!

!Object methodsFor: 'testing' stamp: 'kph 10/28/2006 15:28'!
askFor: selector

^(self respondsTo: #selector) ifTrue: [ self selector ] ifFalse: [ false ]! !

which has a different meaning than what was written above.

And I take the meaning as if self is an instance of a class that responds to the selector #selector then [ and I'd be very curious to know how the compiler handles the if true clause ] else return false.

So this won't work no how.

To see something that will look at the implementors containing #perform .
And read more smalltalk literature.

Yours in service, -- Jerome Peace
10-31-06 08:00   
The second attempt reads:

'From Squeak3.9gamma of ''23 July 2006'' [latest update: 0007065] on 31 October 2006 at 12:54:39 am'!

!Object methodsFor: 'testing' stamp: 'kph 10/31/2006 00:53'!
askFor: selector
    ^ (self respondsTo: selector)
        ifTrue: [ self selector] ifFalse: [ false ]! !

You need to prove to someone that this works.

Try 2 things
first change arguement name to something that is not also a method name. (the name #selector has several implementors in 7066)

and then see if it will actually compile.

Then see what it does when compiled.

I would never use the true clause you have selected. It probably does not work as you intend. And even if it does the fact that a code reader would be confused by the possible ambiguity of the clause makes it something to steer away from.

The other important thing to do here is to write some test code or do-its to prove that it works as you intend. Always prove to yourself that your code works before you try proposing it to others. Save yourself some embarassment.

Coding is like pinball. Only if you do it well do you get a chance to do it again.

To me this code points out a lot of weaknesses in the coder. You are going to have to work (and study) really hard to live this one down.

Yours in service, --Jerome Peace
12-27-06 08:54   
This seems to have some utility, but I'm not convinced that it is worth its weight.

It can work only with a unary selector, and is useful only if the answer could not possibibly be false.

    try: aSelector ifNotUnderstood: aBlock

would be a bit more useful.

    try: aSelector withArguments: aCollection ifNotUnderstood: aBlock

would be more useful still, but it would be much less readable than the code that just askes the respondsTo: question and then sends the message.

In addition, respondsTo: only checks if the selector is in the method dictionary. The method might be abstract, in which case it would still not be understood. Or there might be clever code in the doesNotUnderstand: method ...

the overall outcome might be that this method adds more confusion.
01-05-07 20:31   
Example of use

(myObject askFor: #isMyModel) ifTrue:[ ... ]
01-06-07 01:27   
Hi Keith,

I still don't see this method's worth.

I would either write:

(myObject respondsTo: #isMyModel) and: [ myObject isMyModel] .

or I would define a backstop for isMyModel in Object.

The main negative for me is that askFor: returns a boolean but does not guarentee the return of a boolean. That increases its surface area and increases the care with which it needs to be employed.

As one who finds bugs by reading code, I value clarity above all else.
Methods that are easy to follow and easy to understand. And maintainence is hard enough without introducing tricky code.

I still think you should give this one up to the learning experience and leave it go.

Yours in service, --Jerome Peace
01-06-07 04:02   
Simply because.

1. you dont want to always have to add #is... methods to Object
1b as a user of a sub-system I am not always the provider of the sub-system. As the user it is not my responsibility to provide #is... methods on Object for everything that I might use from someone else. (see 3 for the providers options)

2. In the past it was part of another smalltalk dialect and it was genuinely useful
3. In a system where parts are liberally going to be ripped out it is a useful mechanism that is tolerant of bits that may or may not be present. At present there is only one tolerant mechanism in place i.e. #respondsTo: this is too generic and less readable for this use-case. #askFor: enables a more specific idiom. As a provider of a sub-system, I can if I wish provide #is... methods on object. But what if my sub-system, or another related sub-system that I am intending to use is not loaded by the user at run time.

If I am going to contribute to 3.10 I want this to be present, because I think it may be key to a number of ideas I have in mind. If it turns out to be worthless then by all means remove it after testing has shown that it is not needed. If I have anything to do with 3.10 then its in, at least as an experiment.

If you want #askFor: can be constrained to return a boolean. ( implements this)

The usefulness of #askFor:ifAbsent: would really be curtailed if similarly constrained.

surname := myFriend askFor: #surname ifAbsent: [ 'Smith' ]

would be
surname := (myFriend respondsTo: #surname) ifTrue: [ myFriend surname ] ifFalse: [ 'Smith' ].

01-07-07 02:07   

I'll buy that :

surname := myFriend askFor: #surname ifAbsent: [ 'Smith' ] .

would be useful.

And I have no need for it to be constrained. Reading the if absent part clues you in to the answers type.

I stand by my reluctance for #askFor: It returns false and not nil. That makes it a hybrid and will temp the building of foggy code.
I've come across enough foggy code bugs to last a lifetime.

Constraining it to a boolean would curtail its usefulness.
Have it return nil and I won't have much objection left.

[OT] Its been easy to notice your energy and enthusiam for contributing to squeak. That's why I bothered responding early in the first place. That energy is most useful if you accompany it with clarity in your code and in your communications. The more fully you've explained things the more I've understood. Please take time to do more of that explaining as you continue to contribute.


Yours in service, --Jerome Peace
01-09-07 07:46   
> Please take time to do more of that explaining as you continue to contribute.

sure, as long as I am not making it up as I go along :-)

options: "a) value or nil" "b)true or false"

option a) makes

isItTheRightType = (myObject askFor: #isEric) ifNil: [ false ]

virtually equivalent to askFor:ifAbsent: making that one redundant.

(myObject askFor: #isEric) ifNotNilDo: [ :anEric | ... ]

So we would settle on askFor: returning value or nil, and forget askFor:ifAbsent:

(if I could only remember the original behaviour it would make this all a bit easier)
01-09-07 09:15   
Hi Keith,

As a design value or nil is more flexible than true or false.

Also askFor: #method ifAbsent: [ ] should be implemented.

It is not the same as #askFor:

It will distinguish between the case where the #method is present and when it is not. You may want that to have side effects on the way to delivering the answer.

You can define #askFor: in terms of askFor: #method ifAbsent:[ ] but not the other way around. The pattern abounds in squeak.

Yours in service, --Jerome Peace
01-21-08 22:20   
And as soon as I hit a use case... if find that a) value or nil, just is not the behavior that I am looking for... I want true or false.

01-22-08 05:31   
Hi Keith,
>And as soon as I hit a use case... if find that a) value or nil, just is not the behavior that I am looking for... I want true or false.

2) You are being too terse for me to understand. What is your use case?

If your use case entails askfor returning true or false when the selector is understood then:

(self askFor: #isItCodeYet ) == true
  ifTrue: [...]
 ifFalse: [...] .

would seem to me to cover it.

Secondly, ProtoObject does not understand #perform: .

It is probably still bad form to place a method in a class with does not inherit the protocol.

It would be more elegant to define this in Object where #perform: is known.

Thank you for including #askFor:ifAbsent: that to my mind is still the more useful form of this behavior.

Cheers, -Jer