On Sun, Jul 24, 2016 at 11:14 PM, Eric Velten de Melo
<ericvm...@gmail.com> wrote:
> Actually I wanted to have many different object instances with different
> behaviours picked at random from a list of available behaviours, but didn't
> find practical to create a class for each different method implementation
> and delegating to it, since there are many, possibly unlimited valid
> behaviours.

Maybe each behaviour could have its own method, and an instance
variable stores which method to call.
For example...

  Object subclass: #MyObject
      instanceVariableNames: 'behaviour'
      classVariableNames: ''
      package: 'Example'

Add 'behaviours' protocol and two methods...
    behaviour1
        Transcript crShow: 'Behaviour 1'.

    behaviour2
         Transcript crShow: 'Behaviour 2'.

Add 'initialization' protocol and method...
    initialize
        | behaviours |
        behaviours := self class methods select: [ :m | m protocol =
#behaviours ].
        behaviour := behaviours atRandom selector.

Add 'delegation' protocol and method...
    perform
        self perform: behaviour.

Then from Playground evaluate...
    Transcript open.
    10 timesRepeat: [ MyObject new perform ].

Behaviour 2
Behaviour 2
Behaviour 2
Behaviour 1
Behaviour 2
Behaviour 1
Behaviour 2
Behaviour 2
Behaviour 1
Behaviour 2

Then try...
    MyObject compile:
        'behaviour3
             Transcript crShow: ''Behaviour 3'' '
        classified: #behaviours
        notifying: nil.
     Transcript clear.
     10 timesRepeat: [ MyObject new perform ].

Behaviour 2
Behaviour 1
Behaviour 1
Behaviour 1
Behaviour 3
Behaviour 3
Behaviour 2
Behaviour 1
Behaviour 2
Behaviour 1


HTH, cheers -ben

>
> So maybe changing method implementation at runtime is not what I want
> because the method implementation will be shared among all instances. What I
> had in mind was a functionality similar to prototyped languages like Self
> and Javascript in which you could change the behaviour inside the object and
> not the class/prototype.
>
> 2016-07-23 7:35 GMT-03:00 Norbert Hartl <norb...@hartl.name>:
>>
>> Can you elaborate on the reason why want to modify behaviour? And how you
>> would like it to happen?
>> If the code you want to modify is your own code than you can solve that
>> most of time with the things you already have. Your example using a block
>> might be altered to be a strategy pattern. That means you keep one ore more
>> instance variables for strategy objects. Then you delegate parts of your
>> behaviour to those objects. You can based on context exchange those objects
>> to adjust behaviour.
>> If it is not feasible to change the internal state of an object but you
>> know all possible variants you can implement all variations as methods in
>> the object. The right method can be invoked by doing a double dispatch with
>> another object providing contextual information.
>> There are plenty of possibilities so you need to know what is the context
>> that is responsible for switching behaviour and the requirements of the
>> behaviour modifications. Can you alter the object? Is the number of
>> modifications a fixed number? Does the modification need to be thread safe?
>>
>> Norbert
>>
>> > Am 23.07.2016 um 00:41 schrieb Eric Velten de Melo
>> > <ericvm...@gmail.com>:
>> >
>> > Hello,
>> >
>> > One thing I try to do often is changing the behaviour of a method
>> > dynamically at runtime. The current way I do this is by having a block as 
>> > an
>> > instance variable and having the method call this block, but I find this
>> > approach a bit cumbersome. Is there some other way or is this the
>> > recommended approach?
>> >
>> > I mean, I suppose methods could be changed dynamically by means of
>> > reflection somehow, but is this an easy or recommended way of programming 
>> > in
>> > Smalltalk? Should slots make things easier?
>> >
>> > Eric
>>
>>
>

Reply via email to