Accessing code blocks

Cheers!

I need to do something silly. I need to access the code block as a
variable (to pass it - without evaluating - to another function). How can
I do that?

Is it possible for me to access the “text version of block?” Can I print
out the code that has been attached to my function instead of executing
it?

The only functions that work on code block (that I could find) are:
block_given? and yield. Obviously they do not fit the bill…

Please help.

Grzegorz Dostatni

You can do:

block = proc { |arg|
puts “Here’s the argument: #{arg}”
}

def f(b,arg)
b.call arg
end

proc can be passed around, like in:

f(block,1) # Here’s the argument: 1
f(block,2) # Here’s the argument: 1

With this, you cannot print the code given in proc. If you really need
to access the source of the code, keep the code in the string and eval
to execute it (yack).

Gennady.

···

On Tuesday, July 8, 2003, at 02:05 PM, Grzegorz Dostatni wrote:

Cheers!

I need to do something silly. I need to access the code block as a
variable (to pass it - without evaluating - to another function). How
can
I do that?

Is it possible for me to access the “text version of block?” Can I
print
out the code that has been attached to my function instead of executing
it?

The only functions that work on code block (that I could find) are:
block_given? and yield. Obviously they do not fit the bill…

Please help.

Grzegorz Dostatni

Try this:

def foo(&bar) bar end

bar = foo { |x| x + 1 }

bar.call 1 # => 2

···

On 2003-07-09 06:05:42 +0900, Grzegorz Dostatni wrote:

Please help.


5) “I have challenged the entire quality assurance team to a Bat-Leth
contest. They will not concern us again.”
– Top 12 things likely to be overheard if you had a Klingon Programmer

I need to do something silly. I need to access the code block as a
variable (to pass it - without evaluating - to another function). How can
I do that?

It’s not silly at all, but the syntax isn’t obvious if you haven’t seen it
before.

At the end of your argument list give a named argument preceded with ‘&’.
This converts the block to an explicit Proc object which you can pass
around.

def function1(&blk)
function2(blk)
end

def function2(blk)
blk.call(99)
end

function1 { |i| puts i } #>> prints 99

Is it possible for me to access the “text version of block?” Can I print
out the code that has been attached to my function instead of executing
it?

No, decompiling blocks is not possible AFAIK :slight_smile:

Regards,

Brian.

···

On Wed, Jul 09, 2003 at 06:05:42AM +0900, Grzegorz Dostatni wrote:

Grzegorz Dostatni wrote:

Is it possible for me to access the “text version of block?” Can I print
out the code that has been attached to my function instead of executing
it?

As others have pointed out, this is not possible, atleast not without
jumping through hoops. If you don’t mind jumping through hoops on the
caller side and a little uglier code, here is a quick stab I did at this
earlier:

class X
def first_definition( &binding )
@binding ||= binding
source = binding.call
redefine( source )
end
def redefine( source )
@source = source
@block = eval “Proc.new { #{source} }”, @binding
end
def x(i)
@block.call(i)
end
end
x = X.new
a = 3
x.first_definition { %{|i|a+i} }
puts x.x(2) #=> 5
x.redefine %{|i|a-i}
puts x.x(2) #=> 1

Notice the syntax { %{|i|a+i} }
I wrap a string, “|i|a+i”, inside a block. The block at this level only
serves as a binding, the contents of the string is used to create the
block itself. HTH

···


([ Kent Dahl ]/)_ ~ [ http://www.pvv.org/~kentda/ ]/~
))_student_/(( _d L b_/ (pre-) Master of Science in Technology )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)

You can do:

block = proc { |arg|
puts “Here’s the argument: #{arg}”
}
[…]
With this, you cannot print the code given in proc. If you really need
to access the source of the code, keep the code in the string and eval
to execute it (yack).

Why not parse the string once, to produce a proc object? Then wrap the
string and the proc together in another class, whose objects know both
how to list themselves, and execute themselves, without the overhead of
eval(source_string). Modifying the string should of course re-parse the
block…

As a Ruby nuby, I can’t yet put this into source, but I look forward to
seeing how it can be done.

  • Brian
···

On Wed, 9 Jul 2003 06:22:34 +0900, Gennady bystr@mac.com wrote: