How to check for block in an evaled method?

Consider the snippet -

class B
   def set
     B.class_eval do
        define_method(:a) do |arg|
          if block_given?
            yield
          else
            "hello"
          end
        end
      end
    end
  end

The intention is that block_given? would tell me if the new method a() is
invoked with a block or not.
Now I run this

irb(main):057:0* y = B.new
=> #<B:0x2caf2b8>

irb(main):059:0> y.set
=> #<Proc:0x02cb6784@(irb):45>
irb(main):060:0> y.a
(irb):45: warning: multiple values for a block parameter (0 for 1)
        from (irb):60
=> "hello"

Now if I use with a block

irb(main):061:0> y.a {"bye"}
(irb):45: warning: multiple values for a block parameter (0 for 1)
        from (irb):61
=> "hello"

Oops doesnt work !

Actually the block is being evaled when the method is being created -

irb(main):062:0> y.set {"bye"}
=> #<Proc:0x02cb6784@(irb):45>
irb(main):063:0> y.a
(irb):45: warning: multiple values for a block parameter (0 for 1)
        from (irb):63
=> "bye"

I get that. But the question is, is there a way to check for a block and
then yield in a defined method, as was my naive intention?

Thanks
Nasir

I get that. But the question is, is there a way to check for a block and
then yield in a defined method, as was my naive intention?

Stage 1) Upgrade to ruby 1.9 or later. 2) define_method(:foo) { |arg, &block|
  if block then block.call else puts arg
}

Alternative route is to use string eval.

···

On 8/26/07, Nasir Khan <rubylearner@gmail.com> wrote:

Thanks
Nasir

Hi --

I get that. But the question is, is there a way to check for a block and
then yield in a defined method, as was my naive intention?

Stage 1) Upgrade to ruby 1.9 or later. 2) define_method(:foo) { |arg, &block|
if block then block.call else puts arg
}

I'm not sure. Here's my little test:

   class C
   define_method(:foo) { |arg, &block|
     if block then block.call else puts arg end
   }
   end

   c = C.new
   c.foo(3) { puts "hi" }

which gives me:

   $ /usr/local/lib/ruby-svn/bin/ruby -v block9.rb
   ruby 1.9.0 (2007-08-25 patchlevel 0) [i686-darwin8.10.1]
   3

This is on 1/2-cup coffee so I may well be not seeing something I'm
doing wrong.

David

···

On Mon, 27 Aug 2007, Logan Capaldo wrote:

On 8/26/07, Nasir Khan <rubylearner@gmail.com> wrote:

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

Hi --

>
>>
>> I get that. But the question is, is there a way to check for a block and
>> then yield in a defined method, as was my naive intention?
>>
> Stage 1) Upgrade to ruby 1.9 or later. 2) define_method(:foo) { |arg, &block|
> if block then block.call else puts arg
> }

I'm not sure. Here's my little test:

   class C
   define_method(:foo) { |arg, &block|
     if block then block.call else puts arg end
   }
   end

   c = C.new
   c.foo(3) { puts "hi" }

which gives me:

   $ /usr/local/lib/ruby-svn/bin/ruby -v block9.rb
   ruby 1.9.0 (2007-08-25 patchlevel 0) [i686-darwin8.10.1]
   3

This is on 1/2-cup coffee so I may well be not seeing something I'm
doing wrong.

Well alrighty then... I don't know what thats about and I haven't
installed 1.9ish in a while. I'm surprised that doesn't work but is
valid syntax though. I wonder what is actually happening? Assigning
the (non-existant, and I think impossible) block passed to class C...?

···

On 8/27/07, dblack@wobblini.net <dblack@wobblini.net> wrote:

On Mon, 27 Aug 2007, Logan Capaldo wrote:
> On 8/26/07, Nasir Khan <rubylearner@gmail.com> wrote:

David

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)