How to change the owner of a method in a block?

Hi, let me explain with this simple code:


class A

def initialize(&blk)
blk.call
end

def hello
puts “HELLO !!!”
end

end

a=A.new { hello() }

=> block_1.rb:13: undefined method hello' for main:Object (NoMethodError) from block_1.rb:4:incall’
from block_1.rb:4:in initialize' from block_1.rb:13:innew’
from block_1.rb:13

I understand perfectly what occurs: When passing “hello()” in a block,
it’s like if the current object is “main:Object”, for which there is
no “hello” method (of course).

Well, I’d like that “hello()” would be runned as class A instance
method. Is it possible is some ellegant way?

Thanks a lot.

one way would be to use instance_eval :

def new(&blk)
instance_eval &blk
end

Lex W. wrote:

one way would be to use instance_eval :

def new(&blk)
instance_eval &blk
end

I meant to write :

def initialize(&blk)
instance_eval &blk
end

too much java can get you high .

2008/9/10, Lex W. [email protected]:

instance_eval &blk

end

Really great :slight_smile:

Let me just a question: how does affect using “instance_eval” in
performance? I’ve done some simple tests:

Benchmark.realtime { a=123; a2=a2; a3=a3 }

=> 1.97887420654297e-05

Benchmark.realtime { instance_eval ‘a=123; a2=a2; a3=a3’ }

=> 4.50611114501953e-05

Well, it seems that using “instance_eval” takes the double of time
than running the code directly. Is it significant?

Thanks.

From: Iñaki Baz C. [mailto:[email protected]]

>> Benchmark.realtime { instance_eval ‘a=123; a2=a2; a3=a3’ }

# => 4.50611114501953e-05

that’s a string.

include a block, eg

Benchmark.realtime { a=123; a2=a2; a3=a3 }
=> 1.59740447998047e-05

Benchmark.realtime { instance_eval ‘a=123; a2=a2; a3=a3’ }
=> 7.58171081542969e-05

Benchmark.realtime { instance_eval {a=123; a2=a2; a3=a3} }
=> 2.288818359375e-05

2008/9/10, Peña, Botp [email protected]:

=> 2.288818359375e-05
You are right!
So using “instance_eval” is ~ 40% slower than running directly the
code.

Thanks a lot.

On Wed, Sep 10, 2008 at 7:24 PM, Iñaki Baz C. [email protected] wrote:

So using “instance_eval” is ~ 40% slower than running directly the code.

well, we can try again :slight_smile:

botp@jedi-hopeful:~$ cat test.rb
require ‘benchmark’
n=100_000
Benchmark.bmbm do |x|
x.report(“normal”) { n.times { a=nil;a=123; a2=a2; a3=a3 }}
x.report(“string”) { n.times {instance_eval ‘a=nil;a=123; a2=a2;
a3=a
3’ }}
x.report(“block”) { n.times {instance_eval {a=nil;a=123; a2=a2;
a3=a
3} }}
x.report(“block-broken”) { n.times {a=nil;instance_eval{a=123};
instance_eval{ a2=a2};
instance_eval{a3=a
3}
}
}
end

botp@jedi-hopeful:~$ ruby test.rb
Rehearsal ------------------------------------------------
normal 0.140000 0.000000 0.140000 ( 0.247775)
string 2.420000 0.010000 2.430000 ( 3.438391)
block 0.250000 0.000000 0.250000 ( 0.375656)
block-broken 0.470000 0.010000 0.480000 ( 0.698093)
--------------------------------------- total: 3.300000sec

               user     system      total        real

normal 0.120000 0.000000 0.120000 ( 0.216789)
string 2.480000 0.020000 2.500000 ( 3.291342)
block 0.300000 0.000000 0.300000 ( 0.423327)
block-broken 0.490000 0.000000 0.490000 ( 0.703046)
botp@jedi-hopeful:~$

slower but not slow (in my own mileage :slight_smile:
or optimistically, direct code is faster than a code block

El Jueves, 11 de Septiembre de 2008, botp
escribió:> x.report(“string”) { n.times {instance_eval ‘a=nil;a=123; a2=a2; a3=a3’

string 2.480000 0.020000 2.500000 ( 3.291342)
block 0.300000 0.000000 0.300000 ( 0.423327)
block-broken 0.490000 0.000000 0.490000 ( 0.703046)
botp@jedi-hopeful:~$

slower but not slow (in my own mileage :slight_smile:
or optimistically, direct code is faster than a code block

Good comparision, thanks :slight_smile: