Compute value inside define_method

I know there is a ‘trick’ for forcing a value to compute, but I can’t
seem to remember or find it. The following routine needs to computer
the value of ‘register += 1’ and not insert it literally.

into.class_eval do
define_method “#{dow}_#{tod}_time” do
@registers.get_value( “#{register += 1}”.to_i )
end
…snip…
end

You can see my attempt above, but it doesn’t work. Neither does
‘eval(“register += 1”)’

What’s the trick? or should I approach the problem from a different
angle?

On Tue, Mar 2, 2010 at 5:00 PM, Karl [email protected] wrote:

You can see my attempt above, but it doesn’t work. Neither does
‘eval(“register += 1”)’

What’s the trick? or should I approach the problem from a different
angle?

What is register in your code above? Because this should work:

irb(main):005:0> register = 0
=> 0
irb(main):006:0> “#{register += 1}”.to_i
=> 1
irb(main):008:0> register
=> 1
irb(main):009:0> “#{register += 1}”.to_i
=> 2

On the other hand, if register is already and int and the get_value
method receives an int, why not just:

@registers.get_value(register += 1)

?

Jesus.

On Mar 2, 9:15 am, Jesús Gabriel y Galán [email protected]
wrote:

end
=> 0
@registers.get_value(register += 1)

?

Jesus.

‘register’ is an int.

The problem is one of scope. When this is wrapped in the define_method
it carries as a variable int object when it is included in a class.
Thus, when executed via MyClass.weekeday_morning_time two consecutive
times, ‘register += 1’ increments. I don’t want it to increment when
called, I just need it to increment when it is defining the method.

This is part of a dynamic method creation loop, and the register
values are fixed. The dynamic method creation allows me to create
several hundred methods accessing consecutive registers without
writing all that code. So if I’m defining a method ‘weekday_day_time’
it is ‘get_value’ from register 21. The ‘register += 1’ is just
incrementing the counter through the creation loop.

Make sense? I know, this is a bit obscure.

On Tue, Mar 2, 2010 at 5:25 PM, Karl [email protected] wrote:

         end

method receives an int, why not just:
it carries as a variable int object when it is included in a class.

Make sense? I know, this is a bit obscure.

It’s not a problem of scope. The problem is that define_method
receives a block that closes over the register variable. The block
passed to define_method is not executed when the define_method is
executed, but when the method is invoked, as you have observed. All
defined methods carry the binding to the same register variable and so
every invocation of one of those methods will increment the same
variable. One way to avoid that is force the execution of evaluating
the register variable when defining the method, for example like:

irb(main):012:0> 3.times do |i|
irb(main):013:1* instance_eval “def test_#{i}; #{i};end”
irb(main):014:1> end
=> 3
irb(main):015:0> test_0
=> 0
irb(main):016:0> test_1
=> 1
irb(main):018:0> test_2
=> 2

The *eval method family can also receive a String, which is obviously
not a closure, and so my #{i} above is executed when the instance_eval
is executed. Maybe someone can come up with a cleaner solution.
Translated to your problem (untested):

into.class_eval do
instance_eval <<END
def #{dow}_#{tod}_time
@registers.get_value(#{register += 1})
end
END
…snip…
end

Hope this helps.

Jesus.

On Mar 2, 9:37 am, Jesús Gabriel y Galán [email protected]
wrote:

           @registers.get_value( "#{register += 1}"to_i )

What is register in your code above? Because this should work:
On the other hand, if register is already and int and the get_value
The problem is one of scope. When this is wrapped in the define_method
incrementing the counter through the creation loop.
the register variable when defining the method, for example like:
=> 2
end
END
…snip…
end

Hope this helps.

Jesus.

That was it. I couldn’t remember passing a string to class_eval forces
the computation of #{} strings.

Thanks.

If there’s a better way, of course I’d love to know.