[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Enumerable#inject is surprising me...

Weirich, James

10/6/2003 11:40:00 PM

> 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

3 Answers

nobu.nokada

10/7/2003 12:09:00 AM

0

Hi,

At Tue, 7 Oct 2003 08:39:34 +0900,
Weirich, James wrote:
> > 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
===================================================================
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 Qnil;
+ 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

matz

10/7/2003 3:53:00 AM

0

Hi,

In message "Re: Enumerable#inject is surprising me..."
on 03/10/07, nobu.nokada@softhome.net <nobu.nokada@softhome.net> writes:

|> ['a'].inject(''){break 'b'} # => 'b'
|
|But this doesn't work as Nathaniel expected. It returns last
|iteration value, "".

Commit the fix, please.

matz.

Robert Klemme

10/7/2003 12:53:00 PM

0


"Yukihiro Matsumoto" <matz@ruby-lang.org> schrieb im Newsbeitrag
news:1065498757.424696.31758.nullmailer@picachu.netlab.jp...
> Hi,
>
> In message "Re: Enumerable#inject is surprising me..."
> on 03/10/07, nobu.nokada@softhome.net <nobu.nokada@softhome.net>
writes:
>
> |> ['a'].inject(''){break 'b'} # => 'b'
> |
> |But this doesn't work as Nathaniel expected. It returns last
> |iteration value, "".
>
> Commit the fix, please.

Could you please explain why there is something that needs fixing? To me
this seems perfecly ok. I don't know what's wrong here:

irb(main):001:0> a=(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
irb(main):002:0> a.inject {|*args| p args}
[1, 2]
[nil, 3]
[nil, 4]
[nil, 5]
[nil, 6]
[nil, 7]
[nil, 8]
[nil, 9]
[nil, 10]
=> nil
irb(main):003:0> a.inject("*") {|*args| p args}
["*", 1]
[nil, 2]
[nil, 3]
[nil, 4]
[nil, 5]
[nil, 6]
[nil, 7]
[nil, 8]
[nil, 9]
[nil, 10]
=> nil
irb(main):004:0> [].inject("*") {|*args| p args}
=> "*"
irb(main):005:0> [].inject {|*args| p args}
=> nil
irb(main):006:0> [1].inject {|*args| p args}
=> 1
irb(main):007:0> [1].inject("*") {|*args| p args}
["*", 1]
=> nil
irb(main):008:0> [1].inject("*") {|*args| break args}
=> ["*", 1]
irb(main):009:0> [].inject(){|*args| break args}
=> nil
irb(main):010:0> ['a'].inject(){|*args| break args}
=> "a"
irb(main):011:0> ['a'].inject(''){|*args| break args}
=> ["", "a"]
irb(main):012:0>

Thanks!

robert