From: benjohn@... Date: 2008-06-04T15:28:38+09:00 Subject: Re: Beginner help > 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