neatest way to extend Struct

M

Martin DeMello

I want a Structlike class that takes a hash constructor, so I can say

class A < MyStruct.new(*keys); end

a = A.new:)key1 => val1, :key2 => val2)

Is there any way to base this off Struct?

martin
 
S

Siep Korteling

Martin said:
I want a Structlike class that takes a hash constructor, so I can say

class A < MyStruct.new(*keys); end

a = A.new:)key1 => val1, :key2 => val2)

Is there any way to base this off Struct?

martin
It'standard:

require 'ostruct'

(...)

hash = { "country" => "Australia", :population => 20_000_000 }
data = OpenStruct.new(hash)

p data # -> <OpenStruct country="Australia"
population=20000000>

(code from documentation)

hth,

Siep
 
J

Joel VanderWerf

Martin said:
I want a Structlike class that takes a hash constructor, so I can say

class A < MyStruct.new(*keys); end

a = A.new:)key1 => val1, :key2 => val2)

Is there any way to base this off Struct?

martin

Something based on this, maybe? I hope Struct#members preserves order...

class A < Struct.new:)a, :b)
def initialize(h)
super *h.values_at(*self.class.members.map {|s| s.intern})
end
end

a = A.new:)a => 1, :b => 2)
p a # ==> #<struct A a=1, b=2>
 
D

David A. Black

Hi --

I want a Structlike class that takes a hash constructor, so I can say

class A < MyStruct.new(*keys); end

a = A.new:)key1 => val1, :key2 => val2)

Is there any way to base this off Struct?

Do you need to use inheritance, as opposed to just instantiating
MyStruct directly? I'm thinking of, for example:

class MyStruct < Struct
def self.new(*keys)
s = super
s.class_eval do
define_method:)initialize) do |hash|
hash.each {|k,v| send("#{k}=",v) }
end
end
s
end
end

A = MyStruct.new:)a,:b)
a = A.new:)a => 1, :b => 2)
p a.b # 2


David

--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!
 
M

Martin DeMello

Do you need to use inheritance, as opposed to just instantiating
MyStruct directly? I'm thinking of, for example:

class MyStruct < Struct
def self.new(*keys)
s = super
s.class_eval do
define_method:)initialize) do |hash|
hash.each {|k,v| send("#{k}=",v) }
end
end
s
end
end

Doh - of course, since you aren't inheriting from Struct, you
shouldn't be inheriting from MyStruct either :) Wasn't thinking
clearly enough about the problem. Thanks!

martin
 
R

Robert Klemme

Doh - of course, since you aren't inheriting from Struct, you
shouldn't be inheriting from MyStruct either :) Wasn't thinking
clearly enough about the problem. Thanks!

Why inheritance at all? Why do too much?

irb(main):001:0> MyStruct = Struct.new :foo, :bar do
irb(main):002:1* def initialize(h={})
irb(main):003:2> members.each {|m| self[m] = h[m.to_sym]}
irb(main):004:2> end
irb(main):005:1> end
=> MyStruct
irb(main):006:0> ms = MyStruct.new:)bar => 1, :foo => 2)
=> #<struct MyStruct foo=2, bar=1>

Kind regards

robert
 
E

Eric Hodel

Why inheritance at all? Why do too much?

irb(main):001:0> MyStruct = Struct.new :foo, :bar do
irb(main):002:1* def initialize(h={})
irb(main):003:2> members.each {|m| self[m] = h[m.to_sym]}
irb(main):004:2> end
irb(main):005:1> end
=> MyStruct
irb(main):006:0> ms = MyStruct.new:)bar => 1, :foo => 2)
=> #<struct MyStruct foo=2, bar=1>

Hey, neat! I didn't know you could do that!

I've always reopened the class.
 
M

Martin DeMello

Why inheritance at all? Why do too much?

Because I'd have to repeat that for every new struct I created. But
that's a very neat trick indeed!

martin
irb(main):001:0> MyStruct = Struct.new :foo, :bar do
irb(main):002:1* def initialize(h={})
irb(main):003:2> members.each {|m| self[m] = h[m.to_sym]}
irb(main):004:2> end
irb(main):005:1> end
=> MyStruct
irb(main):006:0> ms = MyStruct.new:)bar => 1, :foo => 2)
=> #<struct MyStruct foo=2, bar=1>
 
R

Robert Klemme

2008/10/23 Martin DeMello said:
Because I'd have to repeat that for every new struct I created. But
that's a very neat trick indeed!

Oh, you want another Struct implementation that does this? I wasn't
aware of this. That's easily fixed.

class MyStruct < Struct
def initialize(h={})
members.each {|m| self[m] = h[m.to_sym]}
end
end

s1 = MyStruct.new :foo, :bar
p s1.ancestors, s1.new:)bar => 123)

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top