Procs and context

According to the Pickaxe:

···

new Proc.new [{| | block } ] -> aProc

Creates a new Proc object, bound to the current context. It may be called
without a block only within a method with an attached block, in which case
that block is converted to the Proc object.

But if i try to convert the block into a proc and rebind it “to the current
context” it fails. In the following snippet, i wish that the proc that is
defined in main context, be rebound into a Room’s context.


def method_missing(action)
puts "#{action}…in the city"
end

class Room
def method_missing(action)
puts "#{action}…in the the privacy of your own room"
end

def live(&block)
instance_eval { Proc.new.call }
end

def initialize
put_feet_on_table
snore
end
end

walk
go_to_work

room = Room.new
room.live do
walk_around_naked!
end

output:
walk…in the city
go_to_work…in the city
put_feet_on_table…in the the privacy of your own room
snore…in the the privacy of your own room
walk_around_naked!..in the city

oh dear, how embarassing! :wink:
Please explain, kind sirs. I think i’m understanding the word "context"
wrong. Also, could a proc rebinding possibly be done?

regards
Peter

repeatr wrote:

def live(&block)
instance_eval { Proc.new.call }

Why not just
instance_eval( &block )
which appears to work fine for me. The variable block points to a Proc
of the external block already due to the &-prefix.

Or are you getting at something more complex?

As for why it your original code doesn’t work:
instance_eval { Proc.new.call }
instance_eval only changes the context of the given block (which
contains Proc.new.call), but Proc.new.call fetches another block/Proc
(&block) from the outside of the method, and that Proc does NOT get
its context changed by instance_eval. Why should it? It would make
recursive use of Procs a nightmare.

HTH

···


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 5. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)

def method_missing(action)
puts “#{action}…in the city”
end

class Room
def method_missing(action)
puts “#{action}…in the the privacy of your own room”
end

def live(&block)
instance_eval { Proc.new.call }

Proc.new reifies the passed block, which was already bound to the
external context. Use instance_eval(&block). Note however that only the
value of self is substituted, ie.:

batsman@tux-chan:/tmp$ expand -t2 ag.rb
class Foo
def bar(&block)
a = “inner a”
instance_eval(&block)
end
end

a = “external a”
o = Foo.new
o.bar do
puts “self.id: #{self.id}”
puts “a is #{a.inspect}”
end
puts “o.id: #{o.id}”
batsman@tux-chan:/tmp$ ruby ag.rb
self.id: 537725500
a is “external a”
o.id: 537725500

end

def initialize
put_feet_on_table
snore
end
end

walk
go_to_work

room = Room.new
room.live do
walk_around_naked!
end

output:
walk…in the city
go_to_work…in the city
put_feet_on_table…in the the privacy of your own room
snore…in the the privacy of your own room
walk_around_naked!..in the city

LOL
We have to put this in some tutorial or documentation!

···

On Sat, May 17, 2003 at 02:43:57AM +0900, repeatr wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

  • DDD no longer requires the librx library. Consequently, librx
    errors can no more cause DDD to crash.
    – DDD

From: Kent Dahl [mailto:kentda@stud.ntnu.no]
Sent: 16 May 2003 08:21
To: ruby-talk ML
Subject: Re: procs and context

repeatr wrote:

def live(&block)
instance_eval { Proc.new.call }

Why not just
instance_eval( &block )
which appears to work fine for me. The variable block points to a Proc
of the external block already due to the &-prefix.

Ah that’s it! That one flew straight by underneath the radar.
Even for my supposedly accustomed ruby mind, things fudge up. :slight_smile:

Or are you getting at something more complex?

As for why it your original code doesn’t work:
instance_eval { Proc.new.call }
instance_eval only changes the context of the given block (which
contains Proc.new.call), but Proc.new.call fetches another block/Proc
(&block) from the outside of the method, and that Proc does NOT get
its context changed by instance_eval. Why should it? It would make
recursive use of Procs a nightmare.

Rightly so.
Thank you kindly for the explanation and fix.

with regards
Peter

···

-----Original Message-----

From: Mauricio Fernandez [mailto:batsman.geo@yahoo.com]
Sent: 16 May 2003 09:01
To: ruby-talk ML
Subject: Re: procs and context

def method_missing(action)
puts “#{action}…in the city”
end

class Room
def method_missing(action)
puts “#{action}…in the the privacy of your own room”
end

def live(&block)
instance_eval { Proc.new.call }

Proc.new reifies the passed block, which was already bound to the
external context. Use instance_eval(&block). Note however that only the
value of self is substituted, ie.:

batsman@tux-chan:/tmp$ expand -t2 ag.rb
class Foo
def bar(&block)
a = “inner a”
instance_eval(&block)
end
end

a = “external a”
o = Foo.new
o.bar do
puts “self.id: #{self.id}”
puts “a is #{a.inspect}”
end
puts “o.id: #{o.id}”
batsman@tux-chan:/tmp$ ruby ag.rb
self.id: 537725500
a is “external a”
o.id: 537725500

Zoi that is enlightening, with this you’ve cleansed my mind of all the moth
flutterings and dust wisps.

If I may talk myself into understanding, thus with:
instance_eval(&Proc.new)
the proc is converted into a block with its sense of “self” converted.

while with:
instance_eval { Proc.new.call }
a block is created with a self pointing to this object (in this case
redundantly so), while the original proc yonder the mountains is executed
untouched.

end

def initialize
put_feet_on_table
snore
end
end

walk
go_to_work

room = Room.new
room.live do
walk_around_naked!
end

output:
walk…in the city
go_to_work…in the city
put_feet_on_table…in the the privacy of your own room
snore…in the the privacy of your own room
walk_around_naked!..in the city

LOL
We have to put this in some tutorial or documentation!

I hope it doesn’t cause any bad dreams though :wink:

a tip of the hat
Peter

···

-----Original Message-----
On Sat, May 17, 2003 at 02:43:57AM +0900, repeatr wrote: