# Define\_method with block

**URL:** <https://www.ruby-forum.com/t/define-method-with-block/141592>\
**Category:** Ruby\
**Created:** [June 27, 2008, 1:24pm UTC](https://www.ruby-forum.com/t/define-method-with-block/141592 "2008-06-27T13:24:37Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![leslieviljoen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3d9bf3/32.png) [@leslieviljoen](https://www.ruby-forum.com/u/leslieviljoen)\
**Post date:** [June 27, 2008, 1:24pm UTC](https://www.ruby-forum.com/t/define-method-with-block/141592/1 "2008-06-27T13:24:37Z")

</div>

Hi!

Is there a way that methods defined with define\_method can take a block?  
Here’s my fighting module:

module Taikwando  
def self.add\_warrior(n)  
define\_method(n) do  
puts “#{n} fights!”  
yield  
end  
end

def fight(\*names)  
names.each do |n|  
Taikwando.add\_warrior(n)  
end  
end  
end

include Taikwando

…when I require it, I can do this:

> > fight “morpheus”, “neo”  
> > =\> [“morpheus”, “neo”]
> 
> > neo do  
> > ?\> puts “karate chop!”
> 
> > end  
> > neo fights!  
> > LocalJumpError: no block given  
> > from ./kungfu.rb:102:in `neo’  
> > from (irb):5

- the yield does not work. Any ideas?

Les

---

<div class="post-metadata">

**Author:** ![leslieviljoen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3d9bf3/32.png) [@leslieviljoen](https://www.ruby-forum.com/u/leslieviljoen)\
**Post date:** [June 27, 2008, 1:32pm UTC](https://www.ruby-forum.com/t/define-method-with-block/141592/2 "2008-06-27T13:32:49Z")

</div>

2008/6/27 Leslie V. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ```
> from (irb):5
> 
> ```
> 
> - the yield does not work. Any ideas?

AFAIK there is no way (yet) to define a method that needs a block via  
define\_method. I believe you can try to work around this by doing

self.class.class\_eval “def #{m}; puts ‘#{m} fights’; yield; end”

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![leslieviljoen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3d9bf3/32.png) [@leslieviljoen](https://www.ruby-forum.com/u/leslieviljoen)\
**Post date:** [June 27, 2008, 1:51pm UTC](https://www.ruby-forum.com/t/define-method-with-block/141592/3 "2008-06-27T13:51:00Z")

</div>

On 6/27/08, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > ```
> > yield
> > 
> > ```
> > 
> > include Taikwando  
> > neo fights!
> 
> self.class.class\_eval “def #{m}; puts ‘#{m} fights’; yield; end”
> 
> Kind regards
> 
> robert

I can explicitly pass a block to my fight method too, but it’s so ugly:  
neo(lambda do  
puts “flying kick”  
end  
)

---

<div class="post-metadata">

**Author:** ![leslieviljoen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3d9bf3/32.png) [@leslieviljoen](https://www.ruby-forum.com/u/leslieviljoen)\
**Post date:** [June 27, 2008, 2:08pm UTC](https://www.ruby-forum.com/t/define-method-with-block/141592/4 "2008-06-27T14:08:35Z")

</div>

I’ve re-arranged a bit your code… maybe this way can be more  
nice-looking:  
module Taikwando  
def self.add\_warrior(n)  
define\_method(n) do |blk|  
puts “#{n} fights!”  
blk.call  
end  
end

```
   def fight(*names)
           names.each do |n|
                   Taikwando.add_warrior(n)
           end
   end

   def moves (fighter,&block)
     self.send(fighter,block)
   end

```

end

include Taikwando

fight “morpheus”, “neo”  
moves(“neo”) do  
puts “karate chop!”  
end

On Fri, Jun 27, 2008 at 11:48 AM, Leslie V.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![leslieviljoen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3d9bf3/32.png) [@leslieviljoen](https://www.ruby-forum.com/u/leslieviljoen)\
**Post date:** [June 27, 2008, 4:50pm UTC](https://www.ruby-forum.com/t/define-method-with-block/141592/5 "2008-06-27T16:50:01Z")

</div>

2008/6/27 Robert D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> On Fri, Jun 27, 2008 at 1:21 PM, Leslie V. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Hi!
> > 
> > Is there a way that methods defined with define\_method can take a block?  
> > Short answers  
> > 1.8 : No  
> > 1.9 : Yes

1.9 is still a bit inconsistent here IMHO:

irb(main):001:0\> RUBY\_VERSION  
=\> “1.9.0”  
irb(main):002:0\> class Foo  
irb(main):003:1\> define\_method(:bar) do  
irb(main):004:2\* yield 123  
irb(main):005:2\> end  
irb(main):006:1\> end  
=\> #\<Proc:0x7feeea10@(irb):4 (lambda)\>  
irb(main):007:0\> Foo.new.bar {|x| p x}  
LocalJumpError: no block given (yield)  
from (irb):4:in `block (1 levels) in <class:Foo>' from (irb):7 from /opt/lib/ruby/1.9.0/irb.rb:149:in `block (2 levels) in  
eval\_input’  
from /opt/lib/ruby/1.9.0/irb.rb:262:in `signal_status' from /opt/lib/ruby/1.9.0/irb.rb:146:in `block in eval\_input’  
from /opt/lib/ruby/1.9.0/irb.rb:145:in `eval_input' from /opt/lib/ruby/1.9.0/irb.rb:69:in `block in start’  
from /opt/lib/ruby/1.9.0/irb.rb:68:in `catch' from /opt/lib/ruby/1.9.0/irb.rb:68:in `start’  
from /opt/bin/irb19:12:in `’  
irb(main):008:0\> class Foo  
irb(main):009:1\> define\_method(:bar) do |&b|  
irb(main):010:2\* b[123]  
irb(main):011:2\> end  
irb(main):012:1\> end  
=\> #\<Proc:0x7fee49c0@(irb):10 (lambda)\>  
irb(main):013:0\> Foo.new.bar {|x| p x}  
123  
=\> 123  
irb(main):014:0\>

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![leslieviljoen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3d9bf3/32.png) [@leslieviljoen](https://www.ruby-forum.com/u/leslieviljoen)\
**Post date:** [June 27, 2008, 2:55pm UTC](https://www.ruby-forum.com/t/define-method-with-block/141592/6 "2008-06-27T14:55:10Z")

</div>

On Fri, Jun 27, 2008 at 1:21 PM, Leslie V.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi!
> 
> Is there a way that methods defined with define\_method can take a block?  
> Short answers  
> 1.8 : No  
> 1.9 : Yes  
> HTH  
> Robert

–  
[http://ruby-smalltalk.blogspot.com/](http://ruby-smalltalk.blogspot.com/)

* * *

AALST (n.) One who changes his name to be further to the front  
D.Adams; The Meaning of LIFF

---

<div class="post-metadata">

**Author:** ![leslieviljoen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3d9bf3/32.png) [@leslieviljoen](https://www.ruby-forum.com/u/leslieviljoen)\
**Post date:** [June 27, 2008, 9:05pm UTC](https://www.ruby-forum.com/t/define-method-with-block/141592/7 "2008-06-27T21:05:41Z")

</div>

On Fri, Jun 27, 2008 at 4:45 PM, Robert K.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 2008/6/27 Robert D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > On Fri, Jun 27, 2008 at 1:21 PM, Leslie V. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> > 
> > > Hi!
> > > 
> > > Is there a way that methods defined with define\_method can take a block?  
> > > Short answers  
> > > 1.8 : No  
> > > 1.9 : Yes  
> > > Good of Robert to point out that 1.9 is not yet stable of course, but  
> > > this is a feature that will work :).  
> > > Cheers  
> > > Robert

–  
[http://ruby-smalltalk.blogspot.com/](http://ruby-smalltalk.blogspot.com/)

* * *

AALST (n.) One who changes his name to be further to the front  
D.Adams; The Meaning of LIFF

---

<div class="post-metadata">

**Author:** ![leslieviljoen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/3d9bf3/32.png) [@leslieviljoen](https://www.ruby-forum.com/u/leslieviljoen)\
**Post date:** [June 27, 2008, 10:08pm UTC](https://www.ruby-forum.com/t/define-method-with-block/141592/8 "2008-06-27T22:08:22Z")

</div>

On 6/27/08, Sandro P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> end
> end
> 
> ```
> 
> end
> 
> include Taikwando
> 
> fight “morpheus”, “neo”  
> moves(“neo”) do  
> puts “karate chop!”  
> end

Ok, that’s a bit better, thanks!

Les
