Easy way to use "self" in Proc

Hi all,

I have this piece of code: http://pastie.caboo.se/198524
I'm trying to use the "self" context of the instanciated class in the
Proc. I've got it working now, but isn't there a nicer way to use the
Proc.new() without having to use the "|obj|" part?

So instead of:

t.code = Proc.new { |obj| obj.instance_test() }

I want to use something like:
t.code = Proc.new { self.instance_test() }

I've tried some stuff but I can't / don't think I can get it working the
second way. Does anyone have some bright ideas about solving this
problem?

Thanks in advance!
Leon

···

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

Hi,

It is possible. You need to tell the object to evaluate the proc with self
as that object like so:

t = Proc.new { self.length }

=> #<Proc:0xb77b7bd8@(irb):1>

"Furry bunny".instance_eval &t <-- note the ampersand. This means pass

the proc as a block.
=> 11

[1, 2, 3].instance_eval &t

=> 3

Because self is an implicit receiver (that is, if no other reciever is
specified, self is the receiver), you can leave off self entirely:

t = Proc.new { length }

=> #<Proc:0xb77ad6ec@(irb):5>

[1, 2, 3].instance_eval &t

=> 3

"Furry bunny".instance_eval &t

=> 11

Dan

···

On Fri, May 16, 2008 at 6:59 PM, Leon Bogaert <leon@tim-online.nl> wrote:

Hi all,

I have this piece of code: http://pastie.caboo.se/198524
I'm trying to use the "self" context of the instanciated class in the
Proc. I've got it working now, but isn't there a nicer way to use the
Proc.new() without having to use the "|obj|" part?

So instead of:

t.code = Proc.new { |obj| obj.instance_test() }

I want to use something like:
t.code = Proc.new { self.instance_test() }

I've tried some stuff but I can't / don't think I can get it working the
second way. Does anyone have some bright ideas about solving this
problem?

Thanks in advance!
Leon
--
Posted via http://www.ruby-forum.com/\.

Leon Bogaert wrote:

Hi all,

I have this piece of code: http://pastie.caboo.se/198524
I'm trying to use the "self" context of the instanciated class in the
Proc. I've got it working now, but isn't there a nicer way to use the
Proc.new() without having to use the "|obj|" part?

So instead of:

t.code = Proc.new { |obj| obj.instance_test() }

I want to use something like:
t.code = Proc.new { self.instance_test() }

I've tried some stuff but I can't / don't think I can get it working the
second way. Does anyone have some bright ideas about solving this
problem?

Fortunately, it's easy:

t.code = Proc.new { self.instance_test() }

and instead of

t.code.call(obj)

you just do this

obj.instance_eval(&t.code)

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Wow, dudes! Thanks!

That's simple... I'll read your posts some more times to really
understand what's hapening :slight_smile:
'Cause this is like magic to me.

After googling on the solution I also found this blog:
http://www.bofh.org.uk/articles/2007/08/16/a-cunning-evil-trick-with-ruby

···

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

I thought I understood the block/proc thing. Guess not...

I thought when I proc is converted to a block, the code gets evaluated.
So (I thought) when Proc.call() is, euhm, called, the proc gets
converted to a block and is getting evaluated in that context.

···

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

Leon Bogaert wrote:

I thought I understood the block/proc thing. Guess not...

I thought when I proc is converted to a block, the code gets evaluated.
So (I thought) when Proc.call() is, euhm, called, the proc gets converted to a block and is getting evaluated in that context.

The block keeps the original context ("lexical scoping"), including local vars, self, and constants:

class C
   class D; end
   def foo
     local = 1
     proc { [local, self, D] }
   end
end

class D; end
local = 2
p [local, self, D]

p C.new.foo.call

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407