On Wed, Mar 13, 2013 at 2:05 PM, Josh Cheek <[email protected]> wrote:
> Change `block_given?` to `block`. The block_given? macro is checking if
> method_missing received a block. Since it didn't the first time you called
> x.hello, it never will (that scope was enclosed).
Are you insinuating that I cannot define a method which will happily
accept a block using define_method and block_given?? You cannot do it
as the example shows:
irb(main):001:0> class X
irb(main):002:1> def self.doit
irb(main):003:2> define_method :foo do |a|
irb(main):004:3* b = block_given?
irb(main):005:3> printf "block: %p\n", b
irb(main):006:3> yield if b
irb(main):007:3> end
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> x = X.new
=> #<X:0x92f057c>
irb(main):011:0> x.foo
NoMethodError: undefined method `foo' for #<X:0x92f057c>
from (irb):11
from /usr/bin/irb:12:in `<main>'
irb(main):012:0> X.doit
=> #<Proc:0x92ed458@(irb):3 (lambda)>
irb(main):013:0> x.foo
ArgumentError: wrong number of arguments (0 for 1)
from (irb):4:in `block in doit'
from (irb):13
from /usr/bin/irb:12:in `<main>'
irb(main):014:0> x.foo 1
block: false
=> nil
irb(main):015:0> x.foo(1) { puts "block called" }
block: false
=> nil
irb(main):016:0> X.doit { puts "x" }
=> #<Proc:0x936bd44@(irb):3 (lambda)>
irb(main):017:0> x.foo(1) { puts "block called" }
block: true
x
=> nil
irb(main):018:0> x.foo(1)
block: true
x
=> nil
Amazing: the block will be captured _even though it is never
referenced explicitly_. Learn something new every day. :-) Thank you
for that!
> Also, you should move the method definition out to a helper method, because
In this particular case I would not define a new method at all.
Basically what happens here is that the class stores the history of
tag names used as method names. I'd rather put the code of the new
method in #method_missing
class XmlDoc
def method_missing(name, *args, &block)
"<#{name}>".tap do |s|
s << yield.to_s if block_given?
end << "</#{name}>"
end
end
irb(main):028:0> xd = XmlDoc.new
=> #<XmlDoc:0x848b374>
irb(main):029:0> xd.foo { xd.bar { 123 } }
=> "<foo><bar>123</bar></foo>"
Btw, I believe there exists a similar mechanism in Ruby already.
http://builder.rubyforge.org/
And btw the reference to temp in the String (original solution) is
useless because the variable is not yet defined at that location.
Cheers
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
--
[email protected] |
https://groups.google.com/d/forum/ruby-talk-google?hl=en
---
You received this message because you are subscribed to the Google Groups
"ruby-talk-google" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.