Stupid OpenStruct question

Ok - I know how to get the fields of an Openstruct object like so

class OpenStruct
def fields
@table.keys.map{|k| k.to_s}
end
end

a = OpenStruc.new()
a.foo = 1
a.bar = 2

a.fields -> [“foo”, “bar”]

Great - ok how do I WORK with these once I have them?

call doesn’t work [] doesn’t work…

I KNOW this is one of those obvious ones that I am somehow
overlooking…

Please tell me the simple straightforward thing I am missing here…

got it

ff = s.fields

ff.each{|g|
puts s.instance_eval g
}
1
2

Terry Smith wrote:

Ok - I know how to get the fields of an Openstruct object like so

class OpenStruct
def fields
@table.keys.map{|k| k.to_s}
end
end

a = OpenStruc.new()
a.foo = 1
a.bar = 2

a.fields -> [“foo”, “bar”]

Great - ok how do I WORK with these once I have them?

call doesn’t work [] doesn’t work…

I KNOW this is one of those obvious ones that I am somehow
overlooking…

Please tell me the simple straightforward thing I am missing here…

Object#send is your friend:

On 24.08.2009 06:02, Terry Smith wrote:

Terry Smith wrote:

a.bar = 2

a.fields -> [“foo”, “bar”]

Great - ok how do I WORK with these once I have them?

Just a remark: if your processing is mainly bases on keys this way then
a Hash might the better data structure. IMHO an OpenStruct is best used
when you are lazy or do not know all the fields that you are going to
use beforehand. I find this especially useful during development, you
can stuff in more and more fields but maybe later change it to a regular
class (or Struct generated class).

Kind regards

robert

maybe you’d be interested in OpenHash? self promotion
(GitHub - karottenreibe/ohash: An OpenStruct replacement, since i hate OpenStruct...)

or Mash
(
http://www.intridea.com/2008/4/12/mash-mocking-hash-for-total-poser-objects?blog=company
)

Both projects try to remove those oddities and incommodities of
OpenStruct.

Greetz!

2009/8/24 Manuel V. [email protected]

2009/8/24 Ralf M. [email protected]:

Robert K. wrote:

On 24.08.2009 06:02, Terry Smith wrote:

Great - ok how do I WORK with these once I have them?

Just a remark: if your processing is mainly bases on keys this way then a
Hash might the better data structure. IMHO an OpenStruct is best used when
you are lazy or do not know all the fields that you are going to use
beforehand. I find this especially useful during development, you can stuff
in more and more fields but maybe later change it to a regular class (or
Struct generated class).

I had a similar experience with using OpenStruct and Hashes and in the end,
I derived my class from OpenStruct (build up a hash within the contructor
and create object with ‘super()’).

I am not sure what you are trying to convey here. Why would I want to
create a class that inherits OpenStruct and build up a Hash
internally? Basically this is what OpenStruct does already:

irb(main):012:0> o = OpenStruct.new
=> #
irb(main):013:0> o.instance_variables
=> [:@table]
irb(main):014:0> o.instance_variable_get(“@table”).class
=> Hash

If you need to much access via Hash methods chances are that you
probably rather want to use a Hash in the first place. That’s what I
meant.

But what do you exactly mean by ‘Struct
generated class’? Is there a smart way of creating abstract classes (without
deriving or explicit coding) from Structs?

Struct.new creates new classes:

irb(main):001:0> NameValue = Struct.new :name, :value
=> NameValue
irb(main):002:0> NameValue.class
=> Class
irb(main):003:0> NameValue.ancestors
=> [NameValue, Struct, Enumerable, Object, Kernel, BasicObject]
irb(main):004:0> nm = NameValue.new “length”, 123
=> #<struct NameValue name=“length”, value=123>
irb(main):005:0> nm.class
=> NameValue

Kind regards

robert

Robert K. wrote:

Just a remark: if your processing is mainly bases on keys this way then a
and create object with ‘super()’).

I am not sure what you are trying to convey here. Why would I want to
create a class that inherits OpenStruct and build up a Hash
internally?
The io-part of my app reads text files and creates objects from them
(csv-like files with named columns).
I use many of the Hash methods internaly, but the OpenStruct gives me
all the accessors for the api and the possibility to create objects from
other input types (eg. hashs or arrays, coming from a database access)
with the same constructor.

Your Struct-example seems more elegant to me. I guess, I should start a
rewrite…

Thanks,
ralf

Robert K. wrote:

a.foo = 1
development, you can stuff in more and more fields but maybe later
change it to a regular class (or Struct generated class).

Hi Robert,
I had a similar experience with using OpenStruct and Hashes and in the
end, I derived my class from OpenStruct (build up a hash within the
contructor and create object with ‘super()’). But what do you exactly
mean by ‘Struct generated class’? Is there a smart way of creating
abstract classes (without deriving or explicit coding) from Structs?

regards
ralf

2009/8/24 Ralf M. [email protected]:

Robert K. wrote:

2009/8/24 Ralf M. [email protected]:

Robert K. wrote:

in more and more fields but maybe later change it to a regular class (or
Struct generated class).

(csv-like files with named columns).
I use many of the Hash methods internaly, but the OpenStruct gives me all
the accessors for the api and the possibility to create objects from other
input types (eg. hashs or arrays, coming from a database access) with the
same constructor.

You are aware that OpenStruct can be constructed with a Hash argument.
If “intern” and “extern” are also separate phases you could work with
Hashes internally and convert them to OpenStruct instances when
handing off to external code.

Your Struct-example seems more elegant to me. I guess, I should start a
rewrite…

:slight_smile: You’ll be interested in method #members:

irb(main):001:0> Struct.new(:foo,:bar).new.members
=> [:foo, :bar]

Kind regards

robert