[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Splat, #to_ary and #to_a

e

9/18/2006 2:13:00 AM

Hi!

I suppose this just qualifies as unexpected (by me) behaviour
but an odd thing happened when I wrote code like this:

[*"foo\nbar"] # => ["foo\n", "bar"]

Mocking out the call sequence for the splat, it seems that
it first checks for #respond_to? :to_ary and, if so, sends
it to the object--the surprising part was that if it does
NOT respond to :to_ary, the splat simply calls #to_a on its
subject.

The idea behind the code, of course, is to have a single
expression that either constructs an Array or reproduces
the current one from whatever object we are dealing with.
This behaviour makes doing so a tad less concise :)

--
Posted via http://www.ruby-....

18 Answers

e

9/18/2006 2:22:00 AM

0

Eero Saynatkari wrote:
> Hi!
>
> I suppose this just qualifies as unexpected (by me) behaviour
> but an odd thing happened when I wrote code like this:
>
> [*"foo\nbar"] # => ["foo\n", "bar"]

On the same topic, this is a strange parsing:

stream.puts ([] << obj).join("\n")

Above is the same as writing:

stream.puts([] << obj).join("\n")


--
Posted via http://www.ruby-....

Yukihiro Matsumoto

9/18/2006 2:41:00 AM

0

Hi,

In message "Re: Splat, #to_ary and #to_a"
on Mon, 18 Sep 2006 11:12:43 +0900, Eero Saynatkari <eero.saynatkari@kolumbus.fi> writes:

|I suppose this just qualifies as unexpected (by me) behaviour
|but an odd thing happened when I wrote code like this:
|
| [*"foo\nbar"] # => ["foo\n", "bar"]

It's fixed in 1.9. 1.8 will remain as it is now for the sake of
compatibility.

matz.


e

9/18/2006 2:56:00 AM

0

Yukihiro Matsumoto wrote:
> Hi,
>
> In message "Re: Splat, #to_ary and #to_a"
> on Mon, 18 Sep 2006 11:12:43 +0900, Eero Saynatkari
> <eero.saynatkari@kolumbus.fi> writes:
>
> |I suppose this just qualifies as unexpected (by me) behaviour
> |but an odd thing happened when I wrote code like this:
> |
> | [*"foo\nbar"] # => ["foo\n", "bar"]
>
> It's fixed in 1.9. 1.8 will remain as it is now for the sake of
> compatibility.

Thank you for clarification!

> matz.


--
Posted via http://www.ruby-....

Rick DeNatale

9/18/2006 3:28:00 AM

0

On 9/17/06, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
> Hi,
>
> In message "Re: Splat, #to_ary and #to_a"
> on Mon, 18 Sep 2006 11:12:43 +0900, Eero Saynatkari <eero.saynatkari@kolumbus.fi> writes:
>
> |I suppose this just qualifies as unexpected (by me) behaviour
> |but an odd thing happened when I wrote code like this:
> |
> | [*"foo\nbar"] # => ["foo\n", "bar"]
>
> It's fixed in 1.9. 1.8 will remain as it is now for the sake of
> compatibility.

Hmmmm,

Just what is the fix in 1.9.

Are you saying that
[*"foo\nbar"] #=> ["foo\nbar"]
in 1.9?

How about:
[*(1..4)]
which in 1.8.x produces [1, 2, 3, 4]

and which of these will change in 1.9?

def a(*arg)
p arg
end

a("foo\nbar")
which in 1.8.4 prints ["foo\nbar"]

a((1..3))
prints [1, 2, 3, 4]
a(1..3)
prints [1..3]


a(1..3, "foo\nbar")
prints [1..3, "foo\nbar"]

a(*"foo\nbar")
prints ["foo\n", "bar"]

a(*(1..4))
prints [1, 2, 3, 4]


*a = "foo\nbar"
a gets ["foo\nbar"]
*a = (1..4)
a gets [1..4]
*a = "foo\nbar", (1..3)
a gets ["foo\nbar", 1..3]

I'm not sure that I see a consistent pattern here. But I have to say
that I think that the 1.8.x interpretations of

a(*"foo\nbar")
and
a(*(1..4))

both make sense since the caller is ASKING for the splat, and that
these two seem very similar to the
[*"foo\nbar"]
case which started this.


I've also always been surprised that String#to_a didn't produce an
array of single character strings, instead of splitting the string
into lines, but that's probably just a personal surprise, and I
wouldn't expect that to change.


--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Simen

9/18/2006 6:15:00 AM

0

On 9/18/06, Eero Saynatkari <eero.saynatkari@kolumbus.fi> wrote:
> Hi!
>
> I suppose this just qualifies as unexpected (by me) behaviour
> but an odd thing happened when I wrote code like this:
>
> [*"foo\nbar"] # => ["foo\n", "bar"]
>
> Mocking out the call sequence for the splat, it seems that
> it first checks for #respond_to? :to_ary and, if so, sends
> it to the object--the surprising part was that if it does
> NOT respond to :to_ary, the splat simply calls #to_a on its
> subject.
>
> The idea behind the code, of course, is to have a single
> expression that either constructs an Array or reproduces
> the current one from whatever object we are dealing with.
> This behaviour makes doing so a tad less concise :)
>

Can't you just test whether the object is an Array (or if it supports
the array methods you need)?

x = "foo\nbar"
(x.is_a?(Array) ? x : [x]) # => ["foo\nbar"]
x = %w(a b c)
(x.is_a?(Array) ? x : [x]) # => ["a", "b", "c"]


> --
> Posted via http://www.ruby-....
>
>


--
- Simen

Yukihiro Matsumoto

9/18/2006 7:27:00 AM

0

Hi,

In message "Re: Splat, #to_ary and #to_a"
on Mon, 18 Sep 2006 12:28:18 +0900, "Rick DeNatale" <rick.denatale@gmail.com> writes:

|Just what is the fix in 1.9.
|
|Are you saying that
|[*"foo\nbar"] #=> ["foo\nbar"]
|in 1.9?

Yes. And if you are curious you can try it by yourself.

|How about:
|[*(1..4)]
|which in 1.8.x produces [1, 2, 3, 4]

Currently,

[1..4]

This may be an issue.

|and which of these will change in 1.9?
|
|def a(*arg)
| p arg
|end
|
|a("foo\nbar")
|which in 1.8.4 prints ["foo\nbar"]

["foo\nbar"]

|a((1..3))
| prints [1, 2, 3, 4]

[1..3]

|a(1..3)
| prints [1..3]

[1..3]

|a(1..3, "foo\nbar")
|prints [1..3, "foo\nbar"]

[1..3, "foo\nbar"]

|a(*"foo\nbar")
|prints ["foo\n", "bar"]

["foo\nbar"]

|a(*(1..4))
|prints [1, 2, 3, 4]

[1..4]

| *a = "foo\nbar"
| a gets ["foo\nbar"]

["foo\nbar"]

| *a = (1..4)
| a gets [1..4]

[1..4]

| *a = "foo\nbar", (1..3)
| a gets ["foo\nbar", 1..3]

["foo\nbar", 1..3]

matz.

dblack

9/18/2006 9:00:00 AM

0

Marcelo Alvim

9/18/2006 9:52:00 AM

0

On 9/18/06, Rick DeNatale <rick.denatale@gmail.com> wrote:
> and which of these will change in 1.9?
>
> def a(*arg)
> p arg
> end
>
> a("foo\nbar")
> which in 1.8.4 prints ["foo\nbar"]
>
> a((1..3))
> prints [1, 2, 3, 4]

Does the following happen only to me?

irb(main):001:0> def a(*arg)
irb(main):002:1> p arg
irb(main):003:1> end
=> nil
irb(main):004:0> a((1..3))
[1..3]
=> nil

Using ruby 1.8.4 (2006-04-14) [i386-mswin32].

Thanks,
Alvim.

Daniel Schierbeck

9/18/2006 10:26:00 AM

0

Marcelo Alvim wrote:
> On 9/18/06, Rick DeNatale <rick.denatale@gmail.com> wrote:
>> and which of these will change in 1.9?
>>
>> def a(*arg)
>> p arg
>> end
>>
>> a("foo\nbar")
>> which in 1.8.4 prints ["foo\nbar"]
>>
>> a((1..3))
>> prints [1, 2, 3, 4]
>
> Does the following happen only to me?
>
> irb(main):001:0> def a(*arg)
> irb(main):002:1> p arg
> irb(main):003:1> end
> => nil
> irb(main):004:0> a((1..3))
> [1..3]
> => nil
>
> Using ruby 1.8.4 (2006-04-14) [i386-mswin32].

No, it the way it's supposed to be.

a (1..3) #=> outputs: [1..3]
a *(1..3) #=> outputs: [1, 2, 3]


Cheers,
Daniel

MonkeeSage

9/18/2006 10:36:00 AM

0

We could always have a "hyper-fatsplat" >>*<< [1]. Then it could do
everything at once, plus feed your cats when you go on vacation. ;)

[1] see Perl6's "hyper-fatarrow" -
http://www.nntp.perl.org/group/perl.perl6.lang...

Regards,
Jordan