Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Returned Proc of Symbol#to_proc should raise an ArgumentError when calling #call without receiver parameter #2312

Merged
merged 2 commits into from Apr 24, 2013
Jump to file or symbol
Failed to load files and symbols.
+12 −2
Split
@@ -26,6 +26,9 @@ def to_proc
# we leave the symbol in sym and use it in the block.
#
sym = self
- Proc.new { |*args| args.shift.__send__(sym, *args) }
+ Proc.new do |*args|
+ raise ArgumentError, "no receiver given" if args.empty?
+ args.shift.__send__(sym, *args)
@dbussink

dbussink Apr 24, 2013

Owner

Since we always shift here, would it be better to do a nil check against that?

recv = args.shift
raise ArgumentError, "no receiver given" unless recv
recv.__send__(sym, *args)

Or perhaps already extract the recv in the block arguments?

@dbussink

dbussink Apr 24, 2013

Owner

Something like this:

    Proc.new do |recv, *args|
      raise ArgumentError, "no receiver given" unless recv
      recv.__send__(sym, *args)
    end
@kachick

kachick Apr 24, 2013

Member

Thank you.

recv = args.shift
raise ArgumentError, "no receiver given" unless recv

I'm afraid when receiver is nil.

nil.tap(&:display)

My firstd idea is |recv, *args| .
But that is modified arity number.

@dbussink

dbussink Apr 24, 2013

Owner

Hmm, the arity argument is right yeah. Probably best to with this approach for now then yeah.

@kachick

kachick Apr 24, 2013

Member

Thank you for the catch!

@dbussink

dbussink Apr 24, 2013

Owner

Thank you for having this thought through better than I did when commenting :).

+ end
end
end
@@ -113,6 +113,9 @@ def to_proc
# we leave the symbol in sym and use it in the block.
#
sym = self
- Proc.new { |*args, &b| args.shift.__send__(sym, *args, &b) }
+ Proc.new do |*args, &b|
+ raise ArgumentError, "no receiver given" if args.empty?
+ args.shift.__send__(sym, *args, &b)
+ end
end
end
@@ -12,6 +12,10 @@
obj.should_receive(:to_s).and_return("Received #to_s")
:to_s.to_proc.call(obj).should == "Received #to_s"
end
+
+ it "raises an ArgumentError when calling #call on the Proc without receiver" do
+ lambda { :object_id.to_proc.call }.should raise_error(ArgumentError)
+ end
end
describe "Symbol#to_proc" do