My question is this:  Instead of providing Object#objectSpecificMethod
a string, would it be possible to provide it a block?

Yes, but it is not in the basic class library. You can define a subclass of CompiledMethod that will forward the message to a block. Something like this (I'm using 2.95x syntax; if you have an older version as I think, it will be easy to convert it to the old syntax; or it will whet your appetite so you'll download the latest version and compile it).

CompiledMethod subclass: MethodBlock [
    | closure |
    MethodBlock class >> on: aBlock [
        ^(self numArgs: aBlock numArgs) closure: aBlock
    ]
    closure: aBlock [
        closure := aBlock
    ]
    valueWithReceiver: anObject withArguments: args [
        ^closure valueWithArguments: args
    ]
]

Behavior subclass: ObjectSpecificBehavior [
    Behavior >> isObjectSpecific [ ^false ]
    isObjectSpecific [ ^true ]
]

Object extend [
    implantObjectSpecificBehavior [
        | subclass |
        self class isObjectSpecific ifFalse: [
            subclass := ObjectSpecificBehavior new.
            subclass superclass: self class.
            self changeClassTo: subclass ]
    ]

    objectSpecificMethod: aString [
        self implantObjectSpecificBehavior.
        self class compile: aString
    ]

    objectSpecificMethod: selector do: aBlock [
        self implantObjectSpecificBehavior.
        self class
            addSelector: selector
            withMethod: (MethodBlock on: aBlock )
    ]
]

| obj |
obj := 1 to: 20.
obj
    objectSpecificMethod: #every:
    do: [ :n | obj atAll: (n to: obj size by: 3) ].
(obj every: 3) printNl "(3 6 9 12 15 18 )"


As you can see from the example, blocks don't have access to "self" and instance variables available. This is by design. In Ruby, @abc syntax is resolved at run-time, while in Smalltalk it is resolved at compile-time (you need to know the list of instance variables at compile-time). On the other hand, 99% of the time you can access self from the enclosing environment ("obj" in the example), and you gain the possibility to access the enclosing environment's "self" and instance variables.

Paolo


_______________________________________________
help-smalltalk mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

Reply via email to