[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Using .each with constructors

Ben Zealley

7/20/2006 6:35:00 PM

Is there a nice elegant way of creating several named objects of the
same class? I naively tried

a,b,c,d = 0
[a, b, c, d].each { |o| o = SomeClass.new }

and found that while they get initialised inside the block, they get
destroyed leaving it. I can't believe

a = SomeClass.new
b = SomeClass.new
etc.

is the best way to do it. I can populate an array, but let's
hypothesise that for reasons relating to irritating corporate coding
standards, the variables need specific names... ;)

Thoughts appreciated! Cheers

--
Ben

28 Answers

Patrick Hurley

7/20/2006 6:46:00 PM

0

On 7/20/06, Ben Zealley <transhumanist@gmail.com> wrote:
> is the best way to do it. I can populate an array, but let's
> hypothesise that for reasons relating to irritating corporate coding
> standards, the variables need specific names... ;)

I am sure some of the real Ruby hackers will have a better solution,
but you can do something like:

a,b,c = Array.new(3).map { Foo.new(42) }

pth

James Gray

7/20/2006 6:49:00 PM

0

On Jul 20, 2006, at 1:35 PM, Ben Zealley wrote:

> Is there a nice elegant way of creating several named objects of the
> same class? I naively tried
>
> a,b,c,d = 0
> [a, b, c, d].each { |o| o = SomeClass.new }

>> a, b, c, d = Array.new(4) { |i| String.new(i.to_s) }
=> ["0", "1", "2", "3"]

Hope that helps.

James Edward Gray II


Mike Harris

7/20/2006 7:09:00 PM

0

Ben Zealley wrote:

>Is there a nice elegant way of creating several named objects of the
>same class? I naively tried
>
>a,b,c,d = 0
>[a, b, c, d].each { |o| o = SomeClass.new }
>
>and found that while they get initialised inside the block, they get
>destroyed leaving it. I can't believe
>
>a = SomeClass.new
>b = SomeClass.new
>etc.
>
>is the best way to do it. I can populate an array, but let's
>hypothesise that for reasons relating to irritating corporate coding
>standards, the variables need specific names... ;)
>
>Thoughts appreciated! Cheers
>
>
>
The parallel assignment/array expansion approach suggested by patrick
and james will definitely work. You could also try

[:a,:b,:c,:d].each { |x| eval "#{x} = SomeClass.new" }

dblack

7/20/2006 7:20:00 PM

0

Ben Zealley

7/20/2006 7:23:00 PM

0


Mike Harris wrote:
> The parallel assignment/array expansion approach suggested by patrick
> and james will definitely work. You could also try
>
> [:a,:b,:c,:d].each { |x| eval "#{x} = SomeClass.new" }

I notice the first two can be combined to

a, b, c = Array.new(3) { SomeClass.new }

losing both the .map and the |i|, and that still works (go Ruby! I
continue to be amazed by how much it can work out...). But all of these
leave an anonymous array of the variables sitting around, which doesn't
get GC'd. Can it be done without that, or should I reduce my pedantic
tendencies slightly and live with it? ;)

Thanks for all the great responses!

--
Ben

Trans

7/20/2006 7:45:00 PM

0


Ben Zealley wrote:
> Is there a nice elegant way of creating several named objects of the
> same class? I naively tried
>
> a,b,c,d = 0
> [a, b, c, d].each { |o| o = SomeClass.new }
>
> and found that while they get initialised inside the block, they get
> destroyed leaving it. I can't believe
>
> a = SomeClass.new
> b = SomeClass.new
> etc.
>
> is the best way to do it. I can populate an array, but let's
> hypothesise that for reasons relating to irritating corporate coding
> standards, the variables need specific names... ;)
>
> Thoughts appreciated! Cheers

Surely overkill but:

require 'facet/enumerable/every

a,b,c = ([SomeClass] * 3).every.new

T.


James Gray

7/20/2006 7:47:00 PM

0

On Jul 20, 2006, at 2:25 PM, Ben Zealley wrote:

> I notice the first two can be combined to
>
> a, b, c = Array.new(3) { SomeClass.new }
>
> losing both the .map and the |i|, and that still works

I was just using the i to produce different Strings so you could see
what was going on in the output. ;)

James Edward Gray II


Simon Kröger

7/20/2006 8:15:00 PM

0

Ben Zealley wrote
> [...]
> a, b, c = Array.new(3) { SomeClass.new }
>
> losing both the .map and the |i|, and that still works (go Ruby! I
> continue to be amazed by how much it can work out...). But all of these
> leave an anonymous array of the variables sitting around, which doesn't
> get GC'd. Can it be done without that, or should I reduce my pedantic
> tendencies slightly and live with it? ;)

The array holds references to the new objects, but the objects don't know
that there is an array:

-------------------------------------------
GC.start
p ObjectSpace.each_object(Array) {}
a, b, c = Array.new(3) { Object.new }
p ObjectSpace.each_object(Array) {}
GC.start
p ObjectSpace.each_object(Array) {}
-------------------------------------------

output:
67
68
67

> Thanks for all the great responses!


btw i like

a, b, c = (1..3).map {Object.new}

or

a, b, c = [42] * 3

but only for immutable types.

:)

cheers

Simon

Ben Zealley

7/20/2006 8:21:00 PM

0


Simon Kröger wrote:
> btw i like
>
> a, b, c = (1..3).map {Object.new}

Now that's elegant. Why would you only use it for immutable types?

--
Ben

Simon Kröger

7/20/2006 8:46:00 PM

0

Ben Zealley wrote:
> Simon Kröger wrote:
>> btw i like
>>
>> a, b, c = (1..3).map {Object.new}
>
> Now that's elegant. Why would you only use it for immutable types?

No, that's ok for normal objects, but

a, b, c = [42] * 3

isn't, because:

a, b, c = ["123"] * 3
b << '4'
puts a # => 1234

a, b and c are referencing the same object.

cheers

Simon