[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Beginner help

Justin To

6/3/2008 5:59:00 PM

Hello, I have just started learning Ruby and have already come upon a
problem:

i'm learning and blocks and procs:

def meth(proc)
puts "before proc"
proc.call
puts "after proc"

yield("hi")

if block_given?
puts "block exists"
else puts "D.N.E."
end
end

meth proc {|var1| puts "block" }

prc = lambda do
puts "inside proc"
end

meth(prc)

the main thing i don't understand is how to create a block when the
original method has an argument? and the block takes an argument....

def meth(proc)

meth proc {|var1| puts "block" }
--
Posted via http://www.ruby-....

5 Answers

David A. Black

6/3/2008 6:28:00 PM

0

Hi --

On Wed, 4 Jun 2008, Justin To wrote:

> Hello, I have just started learning Ruby and have already come upon a
> problem:
>
> i'm learning and blocks and procs:
>
> def meth(proc)
> puts "before proc"
> proc.call
> puts "after proc"
>
> yield("hi")
>
> if block_given?

If there's no block, that yield is going to have caused an exception
anyway.

> puts "block exists"
> else puts "D.N.E."
> end
> end
>
> meth proc {|var1| puts "block" }
>
> prc = lambda do
> puts "inside proc"
> end
>
> meth(prc)
>
> the main thing i don't understand is how to create a block when the
> original method has an argument? and the block takes an argument....
>
> def meth(proc)
>
> meth proc {|var1| puts "block" }

meth(proc) {|var1| puts "block" }

Is that what you mean?


David

--
Rails training from David A. Black and Ruby Power and Light:
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
See http://www.r... for details and updates!

Justin To

6/3/2008 6:39:00 PM

0

def meth(proc)
yield("hello")
end

meth(proc) {|var1| puts "block" }

Ok... I think I'm just confused about the above example... when i run
this an error comes up:
blank.rb:5:in `proc': tried to create Proc object without a block
(ArgumentError)
from blank.rb:5

What does this mean? What did I do wrong?

Thanks in advance.
--
Posted via http://www.ruby-....

David Masover

6/3/2008 7:57:00 PM

0

On Tuesday 03 June 2008 13:38:38 Justin To wrote:
> def meth(proc)
> yield("hello")
> end
>
> meth(proc) {|var1| puts "block" }

I'm not sure that's right. Basic way to do this would be:

def meth
yield("hello")
end

meth { |var1| puts "block" }

Looking at your original message, are you wanting to do this with two
blocks/procs? For example:

def meth(some_proc)
some_proc.call 'calling proc'
yield 'calling block'
end

meth(lambda{|x| puts x; puts 'in proc'}) {|x puts x; puts 'in block'}

That is really, really cumbersome to use. I haven't found a good way around
it, though...

> Ok... I think I'm just confused about the above example... when i run
> this an error comes up:
> blank.rb:5:in `proc': tried to create Proc object without a block
> (ArgumentError)
> from blank.rb:5

The 'proc' method, by itself, is trying to create a Proc object. So, for
example:

foo = proc { |var1| puts "block" }

Now "foo" is the proc, and can be passed around.

Simon Krahnke

6/4/2008 1:00:00 AM

0

* Justin To <tekmc@hotmail.com> (20:38) schrieb:

> What does this mean? What did I do wrong?

You are confusing blocks and procs. Every method can have a single
block, which can be tested by block_given? and called by yield. Procs
are Objects that have a call method.

There is no special syntax for defining a method that takes a block:

,----
| def a
| yield 1
| end
|
| a { | n | puts n }
|
| def b(arg)
| yield 1 + arg
| end
|
| b(1) { | n | puts n }
`----

You can turn a block into a Proc:

,----
| def c(&block)
| block.call 1
| end
|
| def d(arg, &block)
| block.call(1 + arg)
| end
`----

That's in fact what the proc method does:

,----
| p = proc { | n | puts n }
| p.call 1
`----

mfg, simon .... l

benjohn

6/4/2008 6:29:00 AM

0

> def meth(proc)
> yield("hello")
> end
>
> meth(proc) {|var1| puts "block" }
>
> Ok... I think I'm just confused about the above example... when i run
> this an error comes up:
> blank.rb:5:in `proc': tried to create Proc object without a block
> (ArgumentError)
> from blank.rb:5
>
> What does this mean? What did I do wrong?

Definitely read the other answers in this thread. I'll try to add some
more explaination.

What's going wrong here is that "proc" is a function in the module Kernal,
and you're trying to use it as a variable (kind of). This will make sense
at the end...

The slightly confusing thing is that Matz thought it was so useful to be
able to pass a bloc to a function, that he included a specicial syntax to
allow at least one to be passed with as little fuss as possible (I think I
agree).

You simply do this:

def meth
yield("hello")
end

meth {|var1| puts "block passed '#{var1}'" }

So the block is passed in as a kind of special hidden argument. The
special function "yield" will call the block that's passed like this. The
rational (which I think is pretty good) is that this is extremely
convenient in the very regular case of only one block being needed by a
function (think of each, map, sort_by, find, find_all, etc).

You can also do this:

def meth(&block_argument)
block_argument.call("hello")
end

meth {|var1| puts "block passed '#{var1}'" }

Here, the "&" notation in "meth"'s definiteion is explicitly picking up
the block that's passed in, and stuffing it in to the parameter
"block_arguent". The class of this thing is a "Proc", which is just an
wrapper object for a block.

Almost finally, you can explicitely build Proc instances using the Kernel
function "proc", which is what you've been inadvertantly calling:

def meth(proc_argument)
proc_argument.call("hello")
end

my_proc = proc {|var1| puts "block passed '#{var1}'" }
meth(my_proc)

Note that here, there's no "&" as part of the definition of "meth" because
proc_argument is a perfectly normal parameter - it's not trying to wrap a
proc passed from the caller.

A further little wrincle is that the "&" can also be used in the oposite way:

def meth
yield("hello")
end

my_proc = proc {|var1| puts "block passed '#{var1}'" }
meth(&my_proc)

... In this case, when used at the call site, it means "take this Proc
instance, unwrap it, and pass it in to the caller using the special block
argument".

Cheers,
Benjohn