Why (1..4).inject(&:+) works?

Hi rubyists,

I was just wondering why,

(1…4).inject(&:+) #=> 10

works ? (in Ruby 1.9.2)

I understand easily these:

(1…4).inject { |s, e| s + e } #=> 10
(1…4).inject(:+) #=> 10

I suppose it’s calling :+.to_proc #=> #Proc:0x2f52d8

irb> def a(&b); b; end
irb> a(&:+)
=> #Proc:0x2f52d8
irb> :+.to_proc
=> #Proc:0x2f52d8

irb> p = a(&:+)
=> #Proc:0x2f52d8
irb> p.arity
=> -1
irb> p.call(1,2)
=> 3
irb> p.call(1)
ArgumentError: wrong number of arguments(0 for 1)

irb> p.call(1,2,3)
ArgumentError: wrong number of arguments(2 for 1)

irb> p.call
ArgumentError: no receiver given

Well, that’s strange: arity = -1, so normally only optional arguments.
And
it expects 1 argument but want 2 ?
“no receiver given” : That means it knows it has a argument to act on
like
a.+(b). How come ?
Would &:+ knows it need some object to act with “+”(o) ?

Have a nice day

Hi,

Can anyone suggest a faster alternative to String.split()? I need to
call it very intensively and its quite a hotspot. I’m using ruby 1.8.7.

Cheers,
James

On Fri, Oct 30, 2009 at 03:23:01AM +0900, James F. wrote:

Hi,

Can anyone suggest a faster alternative to String.split()? I need to call it very intensively and its quite a hotspot. I’m using ruby 1.8.7.

Cheers,
James

use ruby inline

Can anyone suggest a faster alternative to String.split()? I need to
call it very intensively and its quite a hotspot. I’m using ruby 1.8.7.

Cheers,
James

use ruby inline

Thanks for the link - was not aware of that. Will definitely look into
that.

On Oct 29, 2009, at 11:23 , James F. wrote:

Can anyone suggest a faster alternative to String.split()? I need to
call it very intensively and its quite a hotspot. I’m using ruby
1.8.7.

I can suggest you not thread hijack anymore. It is rude and messes up
people who use real mail clients. Start a new mail.

Benoit D. wrote:

Hi rubyists,

I was just wondering why,

(1…4).inject(&:+) #=> 10

works ? (in Ruby 1.9.2)

Works in 1.8.7 too, FWIW.

Benoit D. wrote:

“no receiver given” : That means it knows it has a argument to act on
like
a.+(b). How come ?
Would &:+ knows it need some object to act with “+”(o) ?

a + b is syntactic sugar for a.+(b), or a.send(:+,b) - you can see that
you have one receiver, and one argument.

If you google “symbol to_proc” you’ll find some 1.8 implementations. The
first hit I get is PragDave’s blog where he shows this code:

class Symbol
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
end

Well, that’s strange: arity = -1, so normally only optional arguments. And
it expects 1 argument but want 2 ?

You can see why that is from the implementation above. The method call
must have a receiver (obj), but we know how many other arguments to
take, so it accepts zero or more. It passes them all as arguments to the
method, whose name is the symbol itself.

On Thu, Oct 29, 2009 at 2:14 PM, Benoit D. [email protected]
wrote:

(1…4).inject { |s, e| s + e } #=> 10
irb> p = a(&:+)

irb> p.call
ArgumentError: no receiver given

Well, that’s strange: arity = -1, so normally only optional arguments. And
it expects 1 argument but want 2 ?
“no receiver given” : That means it knows it has a argument to act on like
a.+(b). How come ?
Would &:+ knows it need some object to act with “+”(o) ?

irb(main):001:0> 1.send(:+)
ArgumentError: wrong number of arguments(0 for 1)
from (irb):1:in +' from (irb):1 from /Users/rick/.rvm/ruby-1.9.1-p243/bin/irb:12:in
irb(main):002:0> 1.send(:+, 2)
=> 3
irb(main):003:0> 1.send(:+, 2, 3)
ArgumentError: wrong number of arguments(2 for 1)
from (irb):3:in +' from (irb):3 from /Users/rick/.rvm/ruby-1.9.1-p243/bin/irb:12:in


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

call it very intensively and its quite a hotspot. I’m using ruby
1.8.7.

I can suggest you not thread hijack anymore. It is rude and messes up
people who use real mail clients. Start a new mail.

Was not being rude - was not aware of it. My mail client allows me to
read and write text to people so its about as real as I need it to be.

In fact, I knew about about the 1.8 implementations. I just forgot about
it.
Thank to have cleared my ideas.

The current implementation looks like (of course it must be in C):

class Symbol
def to_proc
@to_proc ||= Proc.new { |*args| args.shift.send(self, *args) }
end
end

2009/10/30 Rick DeNatale [email protected]