How to use a String obj both in Proc.new and for puts

Hi All,

In the appended code I duplicate the text so I can both display it and
define a new Proc. Is there away I can use, say,

text = ‘[*1…n].join(", ")’

in the body of the Proc spec. and thus simply

puts text?

Thanks in advance,
Richard

def example(n)
return Proc.new { [*1…n].join(", ")}
end

puts %q![*1…n].join(", “) ! + " #=>”
puts example(3).call # => 1, 2, 3

Richard wrote:

Hi All,

In the appended code I duplicate the text so I can both display it and
define a new Proc. Is there away I can use, say,

text = ‘[*1…n].join(", ")’

in the body of the Proc spec. and thus simply

puts text?

Are you asking how to create a string that can serve for display and
also
serve as the executable content of a Proc instance?


#!/usr/bin/ruby -w

s = “x = Math.sqrt(2);puts x * x;”

p = Proc.new { eval s }

puts s

p.call()


Output:

x = Math.sqrt(2);puts x * x;
2.0

Or are you asking how to cause the proc object to be executed when you
put
it in this kind of context:

puts proc_object

For the second case, you could create a class that redefines to_s:

class UntestedExample
def to_s
return p.call() # something like this
end
end

ute = UntestedExample.new

puts ute

Is this kind of what you’re looking for?

irb(main):038:0> a = 0
=> 0
irb(main):039:0> command = “a += 1”
=> “a += 1”
irb(main):040:0> eval(command) ; eval(“puts command”)
a += 1
=> nil
irb(main):041:0> a
=> 1

if so then you’d probably do it like this:

irb(main):058:0> def eval_and_print
irb(main):059:1> lambda {|command| eval(command) ; puts command}
irb(main):060:1> end
=> nil
irb(main):061:0> eval_and_print
=> #Proc:[email protected]:59(irb)
irb(main):062:0> [“puts ‘muppet’”].each &eval_and_print
muppet
puts ‘muppet’
=> [“puts ‘muppet’”]
irb(main):063:0> p = eval_and_print
=> #Proc:[email protected]:59(irb)
irb(main):064:0> p.call(“puts ‘muppet’”)
muppet
puts ‘muppet’
=> nil

Except you’d probably use commands that didn’t involve muppets.

Slightly tidied up from irb:

def eval_and_print
lambda {|command| eval(command) ; puts command}
end

then you can pass it to a block:

[“puts ‘muppet’”].each &eval_and_print

or use it with Proc#call:

p = eval_and_print
p.call(“puts ‘muppet’”)


Giles B.
http://www.gilesgoatboy.org


http://gilesgoatboy.blogspot.com

Hi Paul and Giles,

Thank you very much for your responses. You were both great. The code
with commented results appears below.

I’ve got what I wanted using using the print_and_xxx procedure when I
pass the command string as a argument, along with a argument to pass to
the command.

Passing the command string via the call doesn’t seem to offer a way to
pass in an argument to pass on to the procedure. At least, I couldn’t
figure out how to do it. Nevertheless, I am interested to learning
more about how to apply lamda expressions

Again, thank you, guys.

Best wishes,
Richard

======== code ==========
def print_then_test(cmd_string, arg)
puts cmd_string + " => (when n=#{arg})"
puts (Proc.new {|n| eval cmd_string}).call(arg).to_s
end
print_then_test("[*1…n].join(’, ')", 3)

puts ‘====’

def print_and_eval
lambda { |cmd_string| puts cmd_string + " =>"
puts(eval(cmd_string)) }
end
print_and_eval.call("[*1…3].join(’, ')")

=begin
[*1…n].join(’, ') => (when n=3)
1, 2, 3

[*1…3].join(’, ') =>
1, 2, 3
=end

======================