Instance_eval & attribute accessors

There appears to be some bizarre behaviour with instance_eval with a
block. I’m using Andy & Dave’s constructor block technique, and while
I can do:

Mod::Klass::new {
accessor = true
}

It doesn’t work unless I do:

Mod::Klass::new {
self.accessor = true
}

It doesn’t matter whether this is:

def accessor=(a)
    @accessor = a
end

or

attr_accessor :accessor

Note also that it doesn’t matter if I do:

Mod::Klass::new {
accessor=(true)
}

However, if I have a normal function:

Mod::Klass::new {
init_accessor(true)
}

It works just fine.

Can anyone explain why; is this a limitation of instance_eval? Is
there a way to make the first version work without using self? Why
would using the assignment method or accessor be strange? I don’t
necessarily want to have people access the variable directly – most
of the variables have special assignment methods. So … what’s up?

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.10.15 at 22.28.29

After writing this, I realized what the problem was. It’d still be
nice if I could make everything work without “self.”, but this still
seems “strange”.

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.10.15 at 23.16.24

Can anyone explain why; is this a limitation of instance_eval? Is
there a way to make the first version work without using self? Why
would using the assignment method or accessor be strange? I don’t
necessarily want to have people access the variable directly – most
of the variables have special assignment methods. So … what’s up?

This is not a limitation of instance_eval(), it’s just how Ruby works. Both
this example:

Mod::Klass::new {
     accessor = true
}

and this example:

Mod::Klass::new {
    accessor=(true)
}

have the same result: they both assign “true” to a local variable
“accessor”. To use your attribute “writer” methods, you must specify the
receiver (either “self”, or some other instance). I’m pretty sure there’s no
way around this (otherwise it’s ambiguous).

It’s discussed here and there (e.g. in the “When Trouble Strikes” chapter of
“Programming Ruby”), but I bet every Ruby programmer has been gotten by this
gotcha at least once. Well, OK, maybe not Matz :wink:

Hope this helps,

Lyle