Beginner help

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” }

Hi –

On Wed, 4 Jun 2008, Justin To wrote:

yield(“hi”)

if block_given?

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

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

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.

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.

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

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