In ruby 1.6 I use the following quite often to quickly convert to arrays:
a = [ *o ]
If 'o' is already an array, 'a' will be the same. If 'o' is non-nil, 'a' becomes an array with 'o' as a single element. Otherwise, if 'o' is nil, 'a' becomes an empty array. Nice and clean.
However, in 1.8 if 'o' is nil, 'a' becomes an array with a single element nil.
In other words:
in 1.6 [ *nil ] -> []
in 1.8 [ *nil ] -> [ nil ]
Was this incompatibility introduced deliberately or is it a bug that slipped through?
It becomes a problem (or rather inconvenience) in 1.8, as I cannot replace [ *o ] with o.to_a as in 1.6, because ruby 1.8 gives warning "default `to_a' will be obsolete" for instances of user defined classes.
In ruby 1.6 I use the following quite often to quickly convert to arrays:
a = [ *o ]
If 'o' is already an array, 'a' will be the same. If 'o' is non-nil, 'a' becomes an array with 'o' as a single element. Otherwise, if 'o' is nil, 'a' becomes an empty array. Nice and clean.
However, in 1.8 if 'o' is nil, 'a' becomes an array with a single element nil.
Hi Gennady,
you can use the method "Array":
p Array( [ 1, 2, 3, ] )
p Array( "x" )
p Array( nil )
"Gennady Bystritksy" <gfb@tonesoft.com> schrieb im Newsbeitrag news:41DF1E8F.7020404@tonesoft.com...
Hi, rubyists
In ruby 1.6 I use the following quite often to quickly convert to arrays:
a = [ *o ]
If 'o' is already an array, 'a' will be the same.
No, there will be two arrays containing the same references. Note the difference:
foo=%w{a b c d}
=> ["a", "b", "c", "d"]
foo.id
=> 135018196
foo.to_a.id
=> 135018196
[*foo].id
=> 135018196
foo#to_a just returns self while [*foo] creates a new array.
If 'o' is non-nil, 'a' becomes an array with 'o' as a single element. Otherwise, if 'o' is nil, 'a' becomes an empty array. Nice and clean.
However, in 1.8 if 'o' is nil, 'a' becomes an array with a single element nil.
Which is more consistent IMHO.
In other words:
in 1.6 [ *nil ] ->
in 1.8 [ *nil ] -> [ nil ]
Was this incompatibility introduced deliberately or is it a bug that slipped through?
I'd say the 1.6 code is inconsistent and that was fixed in later versions.
It becomes a problem (or rather inconvenience) in 1.8, as I cannot replace [ *o ] with o.to_a as in 1.6, because ruby 1.8 gives warning "default `to_a' will be obsolete" for instances of user defined classes.
You can easily fix this by
class Object; def to_a; [self] end end
Object.new.to_a
=> [#<Object:0x10188a10>]
Note also that there is #to_ary which should be implemented if a class has a reasonable array representation:
ObjectSpace.each_object(Module){|cl| p cl if cl.instance_methods.include? "to_ary" }
I have checked that Array(nil) works fine both in 1.6 and 1.8, thanks for the tip. Nevertheless, [ *o ] feels so much more attractive ;-). And I still do not see the reason for the behavior being changed. Is there any?
Thank you very much,
Gennady.
···
On Jan 7, 2005, at 10:32 PM, Pit Capitain wrote:
Gennady Bystritksy schrieb:
In ruby 1.6 I use the following quite often to quickly convert to arrays:
a = [ *o ]
If 'o' is already an array, 'a' will be the same. If 'o' is non-nil, 'a' becomes an array with 'o' as a single element. Otherwise, if 'o' is nil, 'a' becomes an empty array. Nice and clean.
However, in 1.8 if 'o' is nil, 'a' becomes an array with a single element nil.
Hi Gennady,
you can use the method "Array":
p Array( [ 1, 2, 3, ] )
p Array( "x" )
p Array( nil )
do you maybe also know a nice trick to make it a single-element Array
iff it's not already an Array?
irb(main):001:0> Array("foo\nbar")
=> ["foo\n", "bar"]
This "feature" gives me the creeps.
I didn't know this behavior before, but it is documented.
I know.
I think you
have to define your own method. If you need an example, let me know.
Regards,
Pit
Thanks, I can do that on my own... it's just that I found this
behavior, albeit somehow logical, very confusing in the past.
"Christian Neukirchen" <chneukirchen@gmail.com> schrieb im Newsbeitrag
news:m2hdlqeb11.fsf@lilith.local...
"Robert Klemme" <bob.news@gmx.net> writes:
"Christian Neukirchen" <chneukirchen@gmail.com> schrieb im Newsbeitrag
news:m2pt0eeubv.fsf@lilith.local...
Hello,
do you maybe also know a nice trick to make it a single-element Array
iff it's not already an Array?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ooops, sorry, I overread that. Then of course my proposal is not a
solution.
Btw, for what do you need that? Just curious...
I needed that rather often for convenience stuff (pass a single
argument or a whole array of them etc.).
When I used [*ary] to do that, I had some "mysterious bugs" that only
appeared if the particular string had a newline in it... it really
took me some time to find those bugs.
"Christian Neukirchen" <chneukirchen@gmail.com> schrieb im Newsbeitrag
news:m2d5wde75h.fsf@lilith.local...
"Robert Klemme" <bob.news@gmx.net> writes:
> "Christian Neukirchen" <chneukirchen@gmail.com> schrieb im Newsbeitrag
> news:m2hdlqeb11.fsf@lilith.local...
>> "Robert Klemme" <bob.news@gmx.net> writes:
>>
>>> "Christian Neukirchen" <chneukirchen@gmail.com> schrieb im
Newsbeitrag
>>> news:m2pt0eeubv.fsf@lilith.local...
>>>>
>>>> Hello,
>>>>
>>>> do you maybe also know a nice trick to make it a single-element
Array
>>>> iff it's not already an Array?
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> Ooops, sorry, I overread that. Then of course my proposal is not a
> solution.
>
> Btw, for what do you need that? Just curious...
I needed that rather often for convenience stuff (pass a single
argument or a whole array of them etc.).
Ah, I see. But for methods arguments it works quite good, doesn't it?
def f(*a) p a end
=> nil
f( "aa\nb" )
["aa\nb"]
=> nil
f( "aab" )
["aab"]
=> nil
f( "aab", "bb" )
["aab", "bb"]
=> nil
f( 1,2,3 )
[1, 2, 3]
=> nil
When I used [*ary] to do that, I had some "mysterious bugs" that only
appeared if the particular string had a newline in it... it really
took me some time to find those bugs.
I needed that rather often for convenience stuff (pass a single
argument or a whole array of them etc.).
Ah, I see. But for methods arguments it works quite good, doesn't it?
def f(*a) p a end
=> nil
The splat operator works differently here.
f( "aa\nb" )
["aa\nb"]
=> nil
f( "aab" )
["aab"]
=> nil
f( "aab", "bb" )
["aab", "bb"]
=> nil
f( 1,2,3 )
[1, 2, 3]
=> nil
I usually had the arguments in an array that should be splatted.
···
When I used [*ary] to do that, I had some "mysterious bugs" that only
appeared if the particular string had a newline in it... it really
took me some time to find those bugs.