Metaprogramming - Array initialization

Hi,

In Ruby, we can declare array as explain in the doc:
http://ruby-doc.org/core/classes/Array.html#M002150

That makes possible many kind of use, such as:

Array.new(1, Array.new(3, Array.new(2, Array.new(1))))

=> [[[[nil], [nil]], [[nil], [nil]], [[nil], [nil]]]]

For my needs, I would like to use a code that declare an array of any
arrays that we want. I don't know if it is possible.

If the previous example can be generated using a function like:
my_array = make_array(1, 3, 2, 1)

...this could be awesome!

Thank you for any comments and help.

Regards.

···

--
Posted via http://www.ruby-forum.com/\.

Paul A. wrote:

Hi,

In Ruby, we can declare array as explain in the doc:
class Array - RDoc Documentation

That makes possible many kind of use, such as:

Array.new(1, Array.new(3, Array.new(2, Array.new(1))))

=> [[[[nil], [nil]], [[nil], [nil]], [[nil], [nil]]]]

For my needs, I would like to use a code that declare an array of any
arrays that we want. I don't know if it is possible.

The above is probably not what you want. Look:

>> a=Array.new(3, Array.new(2))
=> [[nil, nil], [nil, nil], [nil, nil]]
>> a[0][1] = 6
=> 6
>> a
=> [[nil, 6], [nil, 6], [nil, 6]]

Try using the block form:

>> a=Array.new(3) {Array.new(2)}
=> [[nil, nil], [nil, nil], [nil, nil]]
>> a[0][1] = 6
=> 6
>> a
=> [[nil, 6], [nil, nil], [nil, nil]]

Hi Joel,

You could construct the string that represents the command that would
generate the multidimensional array creation and lauch it with
instance_eval.

def make_array(input)

result = ""

for i in input
     result = result + "Array.new(#{i},"
end

for i in input
     result = result + ")"
end

instance_eval(result)

end

The code is not very bright (and also a lot of checks on the input values
should be made before executing instance eval) but I hope you get an idea.

Regards,
Vicente

···

On 24 April 2010 23:13, Paul A. <cyril.staff@gmail.com> wrote:

Hi,

In Ruby, we can declare array as explain in the doc:
http://ruby-doc.org/core/classes/Array.html#M002150

That makes possible many kind of use, such as:
>> Array.new(1, Array.new(3, Array.new(2, Array.new(1))))
=> [[[[nil], [nil]], [[nil], [nil]], [[nil], [nil]]]]

For my needs, I would like to use a code that declare an array of any
arrays that we want. I don't know if it is possible.

If the previous example can be generated using a function like:
my_array = make_array(1, 3, 2, 1)

...this could be awesome!

Thank you for any comments and help.

Regards.
--
Posted via http://www.ruby-forum.com/\.

Agree with Joel. Use the block form of the new method, or you'll get
multiple references to the same object.
This piece of code I believe does the trick. (No fault handling included,
and probably not the most elegant, perhaps since I'm quite new to Ruby.)

def make_array(*a)
  a.flatten!
  if a.size > 1
    Array.new(a.shift){make_array(a)}
  elsif a.size == 1
    Array.new(a.shift)
  end
end

irb(main):052:0> make_array(1, 3, 2, 1)
=> [[[[nil], [nil]], [[nil], [nil]], [[nil], [nil]]]]

Best regards,
Rolf

···

On Sat, Apr 24, 2010 at 11:48 PM, Joel VanderWerf <joelvanderwerf@gmail.com>wrote:

Paul A. wrote:

Hi,

In Ruby, we can declare array as explain in the doc:
class Array - RDoc Documentation

That makes possible many kind of use, such as:

Array.new(1, Array.new(3, Array.new(2, Array.new(1))))

=> [[[[nil], [nil]], [[nil], [nil]], [[nil], [nil]]]]

For my needs, I would like to use a code that declare an array of any
arrays that we want. I don't know if it is possible.

The above is probably not what you want. Look:

>> a=Array.new(3, Array.new(2))
=> [[nil, nil], [nil, nil], [nil, nil]]
>> a[0][1] = 6
=> 6
>> a
=> [[nil, 6], [nil, 6], [nil, 6]]

Try using the block form:

>> a=Array.new(3) {Array.new(2)}
=> [[nil, nil], [nil, nil], [nil, nil]]
>> a[0][1] = 6
=> 6
>> a
=> [[nil, 6], [nil, nil], [nil, nil]]

Had a small issue w/1.9.1.

Here is mine (inspired by Vicente's code):

def multi_array(*input)
  instabce_eval input.map {|i| "Array.new(#{i}"}.join(",") + ')' * input.length
end

Definitely a cool way to make arrays.

Cheers,
Ed

Ed Howland

http://twitter.com/ed_howland

···

On Sun, Apr 25, 2010 at 2:08 PM, Vicente Bosch <vbosch@gmail.com> wrote:

Hi Joel,

You could construct the string that represents the command that would
generate the multidimensional array creation and lauch it with
instance_eval.

def make_array(input)

result = ""

for i in input
result = result + "Array.new(#{i},"
end

for i in input
result = result + ")"
end

instance_eval(result)

end

The code is not very bright (and also a lot of checks on the input values
should be made before executing instance eval) but I hope you get an idea.

Regards,
Vicente

On 24 April 2010 23:13, Paul A. <cyril.staff@gmail.com> wrote:

Hi,

In Ruby, we can declare array as explain in the doc:
class Array - RDoc Documentation

That makes possible many kind of use, such as:
>> Array.new(1, Array.new(3, Array.new(2, Array.new(1))))
=> [[[[nil], [nil]], [[nil], [nil]], [[nil], [nil]]]]

For my needs, I would like to use a code that declare an array of any
arrays that we want. I don't know if it is possible.

If the previous example can be generated using a function like:
my_array = make_array(1, 3, 2, 1)

...this could be awesome!

Thank you for any comments and help.

Regards.
--
Posted via http://www.ruby-forum.com/\.

Very instructives and helpful answers. Many thanks!

···

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

A subtle improvement to the function, as I failed to remember that I could
expand an array to multiple arguments again when calling the function
recursively:

def make_array(*a)
  if a.size > 1
    Array.new(a.shift){make_array(*a)}
  elsif a.size == 1
    Array.new(a.shift)
  end
end

-Rolf

···

On Sun, Apr 25, 2010 at 12:19 AM, Paul A. <cyril.staff@gmail.com> wrote:

Very instructives and helpful answers. Many thanks!
--
Posted via http://www.ruby-forum.com/\.

And what about the case of an empty argument list?

def make_array(*a)
   case a.size
   when 0
     raise ArgumentError, "Need at least one dimension"
   when 1
     Array.new(a.shift)
   else
     Array.new(a.shift){make_array(*a)}
   end
end

Kind regards

  robert

···

On 04/25/2010 12:35 AM, Rolf Pedersen wrote:

[Note: parts of this message were removed to make it a legal post.]

A subtle improvement to the function, as I failed to remember that I could
expand an array to multiple arguments again when calling the function
recursively:

def make_array(*a)
  if a.size > 1
    Array.new(a.shift){make_array(*a)}
  elsif a.size == 1
    Array.new(a.shift)
  end
end

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/