Set an instance variable before and after initialize

  • Follow


If possible, I would like to set a instance variable in an object before 
and after its initialize method is executed.

I've been looking at Class#new but it doesn't seem to have access to a 
reference to the object in creation.

A possible workaround would be to place the object in an already created 
hashtable. But I need to know if initialize has been completed or not 
even if callcc is used.

This behavior must be shared by all objects in classes that inherit 
Object.

I try to create Simula style corutines. In Simula all objects have three 
states of execution: active, passive and terminated. An active object is 
executing it's class body (think: Rubys Object#initialize on steroids). 
The first time an object is activated is when it's created with new. 
Within the class body you can call detach to make the object passive and 
pause execution of the class body. Execution is then continued after the 
point where the object was last activated. Within the class body you can 
also call resume wich make the object passive and activates another 
object. Execution is continued again when the other object become 
passive or terminated. Objects can also become active if the procedure 
call is called with the object as an argument.  When execution reach the 
end of the objects class body, the object becomes terminated and can not 
be activated anymore.

You can't do all the things you can do with callcc with this kind of 
corutines but it makes some otherwise hairy programming easy.

-- 
Posted via http://www.ruby-forum.com/.

0
Reply martialis (8) 7/22/2006 10:34:26 PM

The initialize() method, the constructor, is the earliest point at
which you can manipulate an object, because prior to that it does not
exist.  Although I know diddly-doo about coroutines, it sounds to me
like you'd be better off using instances of the hypothetical
"Coroutine" class rather than the class body itself.  Let an
initialized Coroutine stay dormant until it is sent a call() message,
or something like that, and then do its yielding and whatever else
Coroutines do.
	There seems to be a coroutine implementation, according to Wikipedia,
iff you can read Japanese.

	-J

0
Reply Dymaio (59) 7/23/2006 12:24:56 AM


Martin Jansson wrote:
> If possible, I would like to set a instance variable in an object before
> and after its initialize method is executed.
>
> I've been looking at Class#new but it doesn't seem to have access to a
> reference to the object in creation.

class Klass
  def self.new( *args, &blk )
    o = allocate
    o.instance_variable_set( "@foo", "anything")
    o.initialize( *args, &blk )
    o.instance_variable_set( "@bar", "anything")
    o
  end

You could also you #instance_eval { @foo = "anything }

T.

0
Reply transfire (2969) 7/23/2006 1:50:50 AM

Trans wrote:
> Martin Jansson wrote:
>> If possible, I would like to set a instance variable in an object before
>> and after its initialize method is executed.
>>
>> I've been looking at Class#new but it doesn't seem to have access to a
>> reference to the object in creation.
> 
> class Klass
>   def self.new( *args, &blk )
>     o = allocate
>     o.instance_variable_set( "@foo", "anything")
>     o.initialize( *args, &blk )
>     o.instance_variable_set( "@bar", "anything")
>     o
>   end
> 
> You could also you #instance_eval { @foo = "anything }
> 
> T.

This break the chain of inheritance. You would have to reimplement all 
classes that you use; it would be more complicated to use then Thread 
even if it would have the advantage that you could circumvent some of 
Threads limitations. I'm not even sure that it would behave correctly. 
Class#new seem to do more then call allocate and initialize. But I could 
be wrong. Here is the C code for Class#new:

VALUE
rb_class_new_instance(argc, argv, klass)
    int argc;
    VALUE *argv;
    VALUE klass;
{
    VALUE obj;

    obj = rb_obj_alloc(klass);
    rb_obj_call_init(obj, argc, argv);

    return obj;
}

I've looked at rb_obj_call_init, but I can't seem to find it at the 
moment.

My current hack has an ActiveObject class that I use instead of Object. 
In this class I have a method called body instead of initialize. 
initialize is already used to set that damn variable and to call body 
and can not be rewritten. All this of course breaks the chain of 
inherritance.

-- 
Posted via http://www.ruby-forum.com/.

0
Reply martialis (8) 7/23/2006 6:56:55 AM

That won't work: initialize is private. And it might better to
overwrite Object.new, so it works for all classes.

What about singleton? (I mean "include Singleton".)

gegroet,
Erik V. - http://www.erikveen.dds.nl/

----------------------------------------------------------------

 class Object
   def self.new( *args, &blk )
     o = allocate
     o.instance_variable_set( "@foo", "anything")
     o.instance_eval{initialize( *args, &blk )}
     o.instance_variable_set( "@bar", "anything")
     o
   end
 end

 class Foo
   def initialize(baz)
     @baz       = baz
   end

   def bar
     p @foo
     p @bar
     p @baz
   end
 end

 Foo.new(8).bar

----------------------------------------------------------------


0
Reply erikveen (244) 7/23/2006 7:36:29 AM

Damn! You guys are sticklers! You want complete, universally
applicable, 100% bug-free implementations for a general mailing list
question. How much time do I have? ;-)

T.

0
Reply transfire (2969) 7/23/2006 11:54:06 AM

Think about this:

 Write once.
 Read never.
 Use everywhere.

So, yes, "universally applicable" would be nice... ;]

gegroet,
Erik V. - http://www.erikveen.dds.nl/


0
Reply erikveen (244) 7/23/2006 12:39:58 PM

On Sun, 23 Jul 2006, Martin Jansson wrote:

> If possible, I would like to set a instance variable in an object before and
> after its initialize method is executed.

let initialize help you do this then:


harp:~ > cat a.rb
module BeforeAfterInit
   module InstanceMethods
     def before_initialize *a, &b
     end
     def after_initialize *a, &b
     end
     def initialize *a, &b
       before_initialize *a, &b
       r = super
       after_initialize *a, &b
       r
     end
   end
   module ClassMethods
     def before &b
       define_method 'before_initialize', &b
     end
     def after &b
       define_method 'after_initialize', &b
     end
   end
   def self.included other
     other.module_eval{ include InstanceMethods }
     other.extend ClassMethods
     super
   end
end

class C
   include BeforeAfterInit

   before{ @a = 40 }
   after{ @b = 2 }

   def m() @a + @b end
end

p C.new.m



harp:~ > ruby a.rb
42


regards.

-a
-- 
suffering increases your inner strength.  also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama

0
Reply Ara.T.Howard2 (2804) 7/23/2006 2:34:25 PM

7 Replies
33 Views

(page loaded in 0.119 seconds)

Similiar Articles:













7/27/2012 12:17:27 PM


Reply: