Shortcut for x = [x] unless x.is_a?(Array)

Is there any prettier or cleaner way to write

x = [x] unless x.is_a?(Array)

Aryk G. wrote:

Is there any prettier or cleaner way to write

x = [x] unless x.is_a?(Array)

x = x.to_a

Or am I overseeing something?

Regards,

Siep

Aryk G. wrote:

Is there any prettier or cleaner way to write

x = [x] unless x.is_a?(Array)

Lots of caveats, caution and make sure you really, really are thinking
about what you are trying to do. But with that note of skepticism
aside…

I’d guess what you really want is:

x=Array(x)

This will give you the same behaviour for String, Fixnum, TrueClass,
Regexp and Array as your line, and is probably more what you want for
Nil, Range and Hash. I’m second guessing, but this may not be the wisest
way of writing your code.

Are you trying to get around the fact that x=x.to_a default behavior
will be obsoleted in v1.9?

Make sure that is really what you want.

The answer depends on what you are trying to convert from. I’d use
something like this to make sure this is really what you want to
achieve.

TEST=[[1,2,3],(1…3),{:a=>:b},1,“test”,true,nil,/123/]

TEST.each do |x|
puts x.class
puts ‘============================’
puts “#{x.inspect}.to_a => #{x.to_a.inspect}”
puts “[#{x.inspect}] => #{([x]).inspect}”
puts “Array(#{x.inspect}) => #{Array(x).inspect}”
puts ‘============================’
end

OUTPUT

[1, 2, 3].to_a => [1, 2, 3]
[[1, 2, 3]] => [[1, 2, 3]] <----- this seems to be the only
case that you are catering for
Array([1, 2, 3]) => [1, 2, 3]

Range

1…3.to_a => [1, 2, 3]
[1…3] => [1…3]
Array(1…3) => [1, 2, 3]

Hash

{:a=>:b}.to_a => [[:a, :b]]
[{:a=>:b}] => [{:a=>:b}]
Array({:a=>:b}) => [[:a, :b]]

Fixnum

1.to_a => [1]
[1] => [1]
Array(1) => [1]

String

“test”.to_a => [“test”]
[“test”] => [“test”]
Array(“test”) => [“test”]

TrueClass

true.to_a => [true]
[true] => [true]
Array(true) => [true]

NilClass

nil.to_a => []
[nil] => [nil]
Array(nil) => []

Regexp

/123/.to_a => [/123/]
[/123/] => [/123/]
Array(/123/) => [/123/]

=> some warning about default to_a being deprecated

Todd

which is why x=Array(x) would be better.

Mac

On Mon, Mar 10, 2008 at 5:57 PM, Siep K. [email protected]
wrote:

Siep

#to_a can behave differently

x = {}
x = x.to_a
=> [x]

x = {}
x = [x] unless x.is_a?(Array)
=> [{x}]

x = 5
x.to_a
=> some warning about default to_a being deprecated

Todd

On Mon, Mar 10, 2008 at 6:11 PM, Todd B. [email protected]
wrote:

Regards,

x = [x] unless x.is_a?(Array)
=> [{x}]

x = 5
x.to_a
=> some warning about default to_a being deprecated

I should add, too, that Array[] is different than Array().

Todd

On Mon, Mar 10, 2008 at 6:16 PM, Paul M. [email protected]
wrote:

=> some warning about default to_a being deprecated

Todd

which is why x=Array(x) would be better.

Mac

Like your original response, it depends on what you want to do.

x = {}
Array[x] == Array(x)
=> false

In this case – with the result – one encapsulates, the other
modifies. Same thing with NilClass and Range. I added a line to your
code to see this for sure…

TEST=[[1,2,3],(1…3),{:a=>:b},1,“test”,true,nil,/123/]

TEST.each do |x|
puts x.class
puts ‘============================’
puts “#{x.inspect}.to_a gives #{x.to_a.inspect}”
puts “[#{x.inspect}] gives #{([x]).inspect}”
puts “Array(#{x.inspect}) gives #{Array(x).inspect}”
puts “Array[#{x.inspect}] gives #{Array[x].inspect}”
#added this ^^^^^^ one
puts ‘============================’
end

Todd

puts “Array[#{x.inspect}] gives #{Array[x].inspect}”
#added this ^^^^^^ one
puts ‘============================’
end

Todd

Hi Todd,

Array[x] is equivalent to [x].

Mac

On Tue, Mar 11, 2008 at 5:30 AM, Paul M. [email protected]
wrote:

Array[x] is equivalent to [x].
Hi,

I know that now. Just wanted to make sure. Thanks.

Todd

Aryk G. wrote:

Is there any prettier or cleaner way to write

x = [x] unless x.is_a?(Array)

x = [x].flatten

Although I suspect the x = Array(x) method would be faster.

On Tue, Mar 11, 2008 at 6:32 PM, Jeremy Weiskotten
[email protected] wrote:

Aryk G. wrote:

Is there any prettier or cleaner way to write

x = [x] unless x.is_a?(Array)

x = [x].flatten

Although I suspect the x = Array(x) method would be faster.

Yeah, but those are a little different, too…

x = [[1, 2, 3], [1, 2]]
p x.flatten

=> [1, 2, 3, 1, 2]

x = [[1, 2, 3], [1, 2]]
p Array(x)

=> [[1, 2, 3], [1, 2]]

Todd

On Tue, Mar 11, 2008 at 11:37 AM, Todd B. [email protected]
wrote:

Array[x] is equivalent to [x].

Hi,

I know that now. Just wanted to make sure. Thanks.

I think in my head I was thinking of something different anyway…

x = [*x]

…which behaves the same as Array(x), except for x = nil, where it
behaves like [x].

Todd

Paul M. wrote:

=> some warning about default to_a being deprecated

Todd

which is why x=Array(x) would be better.

Mac

(1…3).to_a will not give any warning and will convert it to [1,2,3]

Nikhil W. wrote:

(1…3).to_a will not give any warning and will convert it to [1,2,3]

Object#to_a is being deprecated, so you will get the warning with
classes that don’t implement their own. When they do, as is the case
with Range objects, you won’t see it.
Since the only “hint” that was given in the initial question was that
Array was definitely a possibility as an input, so I assumed that an
unknown class could be set as x. In his actual problem this is almost
certainly more clearly restricted.

Hey guys,

I just read through this whole thread. I’ve really thought this through.

What I was really trying to do all along was this.

x = [x] unless x.is_a?(Array). I know this sounds redundant, buts that
what I want and thats all I want.

In the case of most types, the to_a and Array() can get you by, but when
you don’t know what type it is (especially when it could be a hash), I
defined this function to flat out just do what I want it to do.

class Array
def self.wrap(value)
value.is_a?(Array) ? value : [value]
end
end

Simple, to the point, and no corner cases…is my solution.

So:

g = {:x=>1, :y=>2}
Array.wrap(g)[0].is_a?(Hash) ==> true

Done.