From: Thomas Sawyer <transfire@...>
Date: 2012-03-17T04:24:13+09:00
Subject: [ruby-core:43356] [ruby-trunk - Bug #6151] ArgumentError of lambda shows wrong location


Issue #6151 has been updated by Thomas Sawyer.


How can that be by design? What kind of design criteria says that "instance_eval should blow up if a lambda is passed to it"? 

So you are saying that instance_eval passes the receiver into the Proc as an argument? Why would it do this when the Block has zero arity? Why not just check the arity of the block and pass it if it can take an argument otherwise not?

This snafu is really ashame for me too, b/c I finally had a good reason to use Ruby 1.9's `->` operator!

----------------------------------------
Bug #6151: ArgumentError of lambda shows wrong location
https://bugs.ruby-lang.org/issues/6151#change-24660

Author: Thomas Sawyer
Status: Closed
Priority: Normal
Assignee: 
Category: core
Target version: 2.0.0
ruby -v: ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]


=begin

Perhaps there is a reason, but it sure seems like a bug to me. Given this simple class:

      #
      class BlockParser < BasicObject
        def initialize(data={}, &block)
          @data = data
          instance_eval(&block)
        end

        def method_missing(name, *args, &block)
          if block
            @data[name] = {}
            BlockParser.new(@data[name], &block)
          else
            case args.size
            when 0
              @data[name]
            when 1
              @data[name] = args.first
            else
              @data[name] = args
            end
          end
        end
      end

Then we can do:

      data = {}
      BlockParser.new(data) do
        name 'Tommy'
      end
      data #=> {:name=>'Tommy'}

But,

      data = {}
      blk  = lambda do
        name 'Tommy'
      end
      BlockParser.new(data, &blk)
      ArgumentError: wrong number of arguments (1 for 0)
      	from (irb):44:in `block in irb_binding'
      	from (irb):16:in `instance_eval'
      	from (irb):16:in `initialize'
      	from (irb):46:in `new'
      	from (irb):46
      	from /home/trans/.rbfu/rubies/1.9.3-p0/bin/irb:12:in `<main>'

If I use (({Proc.new})) instead of (({lambda})) it works. But since I am using (({#instance_eval})) to evaluate the Proc, that shouldn't matter.

Note the reported line number of the error corresponds to (({name 'Tommy'})).
=end



-- 
http://bugs.ruby-lang.org/