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

B

Benoit Daloze

[Note: parts of this message were removed to make it a legal post.]

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
 
J

James French

Hi,

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

Cheers,
James
 
R

Reid Thompson

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
 
J

James French

-----Original Message-----
From: Reid Thompson [mailto:[email protected]]
Sent: 29 October 2009 18:29
To: ruby-talk ML
Cc: Reid Thompson
Subject: Re: String.split
=20
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
=20
use ruby inline

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

Ryan Davis

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.
 
B

Brian Candler

Benoit said:
"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.
 
R

Rick DeNatale

Hi rubyists,

I was just wondering why,

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

works ? (in Ruby 1.9.2)

I understand easily these:

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

I suppose it's calling :+.to_proc #=3D> #<Proc:0x2f52d8>

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

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

Well, that's strange: arity =3D -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 lik= e
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 `<main>'
irb(main):002:0> 1.send:)+, 2)
=3D> 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 `<main>'


--=20
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
 
J

James French

-----Original Message-----
From: Ryan Davis [mailto:[email protected]]
Sent: 29 October 2009 19:03
To: ruby-talk ML
Subject: Re: String.split
=20
=20
On Oct 29, 2009, at 11:23 , James French wrote:
=20
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.
=20
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.
 
B

Benoit Daloze

[Note: parts of this message were removed to make it a legal post.]

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top