I'm trying to use instance_eval in a project I'm doing, and I
extracted a very simple example:
class IETest
attr_accessor :foo
end
t = IETest.new
t.instance_eval { self.foo = 'foo' }
puts t.foo
This works as expected. However if I do
t.instance_eval { foo = 'foo' }
then t.foo => nil
I also know that t.instance_eval { @foo => 'foo' } would work in this
case. However, I'm trying to set a Rails attribute, so I have to go
through the method accessor. Is there any way that I can make this
work with just { foo = 'foo' } instead of { self.foo = 'foo' } ?
Pat
t.instance_eval { foo = 'foo' }
Ruby will always see the above as a local variable declaration. There is no way around that.
I also know that t.instance_eval { @foo => 'foo' } would work in this
case. However, I'm trying to set a Rails attribute, so I have to go
through the method accessor.
You've showed one way to handle it. Another is the use write_attribute(), if we are talking about ActiveRecord.
James Edward Gray II
···
On May 8, 2006, at 3:30 PM, Pat Maddox wrote:
No. Define method missing to dispatch calls to "foo" to the accessor, and
change your block just a little bit. E.g.
class IETest
def method_misssing(sym, *args, &blk)
# dispatches any methods missing to "assignment" version of method.
self.__send__(sym + "=", *args, &blk)
end
end
t = IETest.new
t.instance_eval { foo 'foo' } # notice lack of assignment operator
puts t.foo
···
On 5/8/06, Pat Maddox <pergesu@gmail.com> wrote:
I'm trying to use instance_eval in a project I'm doing, and I
extracted a very simple example:
class IETest
attr_accessor :foo
end
t = IETest.new
t.instance_eval { self.foo = 'foo' }
puts t.foo
This works as expected. However if I do
t.instance_eval { foo = 'foo' }
then t.foo => nil
I also know that t.instance_eval { @foo => 'foo' } would work in this
case. However, I'm trying to set a Rails attribute, so I have to go
through the method accessor. Is there any way that I can make this
work with just { foo = 'foo' } instead of { self.foo = 'foo' } ?
Pat
Can I call pass in an object to instance_eval? Let me show you the
full class...
class ScenarioGenerator
def initialize
@rules =
end
def add_rule(&r)
@rules << r
end
def generate
s = Scenario.new
num_players = 0
@rules.each do |r|
r.call(s)
end
s.create_players(num_players) if num_players > 0
s
end
end
The reason I went to r.call(s) is so that I can do
g = ScenarioGenerator.new
g.add_rule { |s| s.sb = 200 }
s then becomes the Scenario that I created.
However I want to be able to modify num_players with a rule, so I need
instance_eval. I still need to be able to pass in the Scenario object
though. How could I do that?
Pat
···
On 5/8/06, James Edward Gray II <james@grayproductions.net> wrote:
On May 8, 2006, at 3:30 PM, Pat Maddox wrote:
> t.instance_eval { foo = 'foo' }
Ruby will always see the above as a local variable declaration.
There is no way around that.
> I also know that t.instance_eval { @foo => 'foo' } would work in this
> case. However, I'm trying to set a Rails attribute, so I have to go
> through the method accessor.
You've showed one way to handle it. Another is the use
write_attribute(), if we are talking about ActiveRecord.
James Edward Gray II
Apparently I can't do that, so I changed the design up a bit so that I
could do {|s| s.num_opponents = 3}.
Thanks for the help James and Justin, I really appreciate it.
Pat
···
On 5/8/06, Pat Maddox <pergesu@gmail.com> wrote:
On 5/8/06, James Edward Gray II <james@grayproductions.net> wrote:
> On May 8, 2006, at 3:30 PM, Pat Maddox wrote:
>
> > t.instance_eval { foo = 'foo' }
>
> Ruby will always see the above as a local variable declaration.
> There is no way around that.
>
> > I also know that t.instance_eval { @foo => 'foo' } would work in this
> > case. However, I'm trying to set a Rails attribute, so I have to go
> > through the method accessor.
>
> You've showed one way to handle it. Another is the use
> write_attribute(), if we are talking about ActiveRecord.
>
> James Edward Gray II
>
Can I call pass in an object to instance_eval? Let me show you the
full class...
class ScenarioGenerator
def initialize
@rules =
end
def add_rule(&r)
@rules << r
end
def generate
s = Scenario.new
num_players = 0
@rules.each do |r|
r.call(s)
end
s.create_players(num_players) if num_players > 0
s
end
end
The reason I went to r.call(s) is so that I can do
g = ScenarioGenerator.new
g.add_rule { |s| s.sb = 200 }
s then becomes the Scenario that I created.
However I want to be able to modify num_players with a rule, so I need
instance_eval. I still need to be able to pass in the Scenario object
though. How could I do that?
Pat