Does it surprise you?
irb(main):001:0> [‘a’].inject{break ‘b’}
=> “a”
Inject works on pairs of elements. Since your list has only one element,
there are no pairs.
You can force one pair in the above example by explicitly supplying an
initial element …
[‘a’].inject(‘’){break ‘b’} # => ‘b’
But even that will break down when you have an empty list.
···
–
– Jim Weirich / Compuware
– Fidelity/FWP Capture Services
– Phone: 859-386-8855
Hi,
Does it surprise you?
irb(main):001:0> [‘a’].inject{break ‘b’}
=> “a”
Inject works on pairs of elements. Since your list has only one element,
there are no pairs.
It’s correct, the code has no iteration.
You can force one pair in the above example by explicitly supplying an
initial element …
[‘a’].inject(‘’){break ‘b’} # => ‘b’
But this doesn’t work as Nathaniel expected. It returns last
iteration value, “”.
Index: enum.c
···
At Tue, 7 Oct 2003 08:39:34 +0900, Weirich, James wrote:
RCS file: /cvs/ruby/src/ruby/enum.c,v
retrieving revision 1.39
diff -u -2 -p -r1.39 enum.c
— enum.c 22 Aug 2003 17:43:57 -0000 1.39
+++ enum.c 7 Oct 2003 00:05:00 -0000
@@ -183,12 +183,12 @@ inject_i(i, memo)
NODE *memo;
{
if (memo->u2.value) {
memo->u2.value = Qfalse;
if (RTEST(memo->u2.value)) {
memo->u1.value = i;
}
else {
memo->u2.value = Qnil;
memo->u1.value = rb_yield_values(2, memo->u1.value, i);
}
return memo->u2.value = Qfalse;
}
@@ -207,6 +207,6 @@ enum_inject(argc, argv, obj)
memo = rb_node_newnode(NODE_MEMO, Qnil, Qtrue, 0);
}
rb_iterate(rb_each, obj, inject_i, (VALUE)memo);
n = memo->u1.value;
n = rb_iterate(rb_each, obj, inject_i, (VALUE)memo);
if (!memo->u2.value) n = memo->u1.value;
rb_gc_force_recycle((VALUE)memo);
return n;
–
Nobu Nakada
Inject works on pairs of elements. Since your list has only one
element, there are no pairs.
It’s correct, the code has no iteration.
Ah, good point. Missed that.
You can force one pair in the above example by explicitly
supplying an
initial element …
[‘a’].inject(‘’){break ‘b’} # => ‘b’
But this doesn’t work as Nathaniel expected. It returns last
iteration value, “”.
Well, at least I was partly right about it not working :-).
Thanks, Jim & Nobu.
Nathaniel
<:((><
···
nobu.nokada@softhome.net [mailto:nobu.nokada@softhome.net ] wrote:
I just tried this on both 1.8.0 and the latest CVS, and it appears to have
been introduced post-1.8.0. I didn’t want anyone to panic when they couldn’t
reproduce the problem
Nathaniel
<:((><
···
nobu.nokada@softhome.net [mailto:nobu.nokada@softhome.net ] wrote:
[‘a’].inject(‘’){break ‘b’} # => ‘b’
But this doesn’t work as Nathaniel expected. It returns last
iteration value, “”.
Hi –
[‘a’].inject(‘’){break ‘b’} # => ‘b’
But this doesn’t work as Nathaniel expected. It returns last
iteration value, “”.
I’m not sure why it would be “”. Wouldn’t that only happen if the
empty string (the inject accumulator) appeared as the last value in
the block? For example:
irb(main):010:0> .inject(‘’) { |a| a }
=> “”
I’m also looking at these two cases:
irb(main):002:0> [‘a’].inject(‘’) { }
=> nil
irb(main):003:0> [‘a’].inject(‘’) { ‘b’ }
=> “b”
Doesn’t “break ‘b’” evaluate to ‘b’ (even though of course it also
breaks)?
David
···
On Tue, 7 Oct 2003 nobu.nokada@softhome.net wrote:
At Tue, 7 Oct 2003 08:39:34 +0900, > Weirich, James wrote:
–
David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav
Hi –
Hi,
[‘a’].inject(‘’){break ‘b’} # => ‘b’
But this doesn’t work as Nathaniel expected. It returns last
iteration value, “”.
Commit the fix, please.
Using the new version:
$ ./ruby -v
ruby 1.8.0 (2003-10-06) [i686-linux]
$ ./ruby -e ‘p [“a”].inject(“start”) {|x,y| “b”}’
“b”
$ ./ruby -e ‘p [“a”].inject(“start”) {|x,y| break “b”}’
“start”
I’m still not understanding why these should be different, or how
“start” gets into the first one (the first block) at all.
David
···
On Tue, 7 Oct 2003, Yukihiro Matsumoto wrote:
In message “Re: Enumerable#inject is surprising me…” > on 03/10/07, nobu.nokada@softhome.net nobu.nokada@softhome.net writes:
–
David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav
Whoops, I mean how it gets into the second one at all.
David
···
On Thu, 9 Oct 2003 dblack@superlink.net wrote:
Using the new version:
$ ./ruby -v
ruby 1.8.0 (2003-10-06) [i686-linux]
$ ./ruby -e ‘p [“a”].inject(“start”) {|x,y| “b”}’
“b”
$ ./ruby -e ‘p [“a”].inject(“start”) {|x,y| break “b”}’
“start”
I’m still not understanding why these should be different, or how
“start” gets into the first one (the first block) at all.
–
David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav
ts1
(ts)
9 October 2003 08:55
10
$ ./ruby -e 'p ["a"].inject("start") {|x,y| break "b"}'
"start"
I'm still not understanding why these should be different, or how
"start" gets into the first one (the first block) at all.
svg% ruby -e 'p ["x", "y"].inject("a") {|x,y| break 12 if y == "y"; x + y}'
"ax"
svg%
#inject ignore the value returned by break, and return the last result.
In your case, because it exit at the first iteration it return the initial
value "start"
Guy Decoux
I haven’t seen the fix committed yet…
Nathaniel
<:((><
···
dblack@superlink.net [mailto:dblack@superlink.net ] wrote:
I’m still not understanding why these should be different, or how
“start” gets into the first one (the first block) at all.
Whoops, I mean how it gets into the second one at all.
I thought that was what was broken, but I believe I’m officially confused,
too
Nathaniel
<:((><
···
dblack@superlink.net [mailto:dblack@superlink.net ] wrote:
#inject ignore the value returned by break, and return the last
result.
I thought “break val” executed a break and generated a
return value for the block at the same time:
irb(main):011:0> a = proc { break 3 } .call; a
=> 3
Why wouldn’t #inject treat the break the same way?
Robert
(Robert)
9 October 2003 14:33
16
“Nathaniel Talbott” nathaniel@NOSPAMtalbott.ws schrieb im Newsbeitrag
news:019801c38e6c$e6ea41f0$c81e140a@abraham…
#inject ignore the value returned by break, and return the last
result.
I thought “break val” executed a break and generated a
return value for the block at the same time:
irb(main):011:0> a = proc { break 3 } .call; a
=> 3
Why wouldn’t #inject treat the break the same way?
I thought that was what was broken, but I believe I’m officially
confused,
too
Welcome to the club. Me too. Does anybody out there (Matz, Nobu) dare to
summarize problem and proposed solution? Thanks!
robert
···
dblack@superlink.net [mailto:dblack@superlink.net ] wrote: