Get OpenStruct attributes

Dear rubyists,

What’s the best way to get the list of attributes of an OpenStruct?

Thanks in advance,
Edgardo

On Thu, Mar 13, 2008 at 04:04:57AM +0900, Ed Hames wrote:

Dear rubyists,

What’s the best way to get the list of attributes of an OpenStruct?

Not perfect, but this might do the trick:

require ‘ostruct’
=> true

x = OpenStruct.new(:foo => ‘asdf’)
=> #

x.methods - OpenStruct.instance_methods
=> [“foo”, “foo=”]

Given this setup:

require ‘ostruct’
=> false

o = OpenStruct.new
=> #

o.field = “this”
=> “this”

o.fold = “that”
=> “that”

o
=> #<OpenStruct field=“this”, fold=“that”>

The “nice” way:

o.methods - Object.methods - OpenStruct.instance_methods
=> [“fold”, “fold=”, “field”, “field=”]

Or maybe go one more level, to kick out the attr= methods:

(o.methods - Object.methods - OpenStruct.instance_methods).reject
{|method| method =~ /=$/ }

The “dirty” way:

o.instance_variable_get("@table")
=> {:field=>“this”, :fold=>“that”}

Jason

On Wed, Mar 12, 2008 at 12:04 PM, Ed Hames [email protected] wrote:

Dear rubyists,

What’s the best way to get the list of attributes of an OpenStruct?

A bit hackish, but

object.methods(nil).grep /[^=]$/

martin

On Wed, Mar 12, 2008 at 12:54 PM, Jason R. [email protected]
wrote:

The “dirty” way:

o.instance_variable_get(“@table”)
=> {:field=>“this”, :fold=>“that”}

That’s actually the cleanest way - it’s proof against singleton
methods being added to the object.

martin

On Mar 12, 3:04 pm, Ed Hames [email protected] wrote:

Dear rubyists,

What’s the best way to get the list of attributes of an OpenStruct?

o = OpenStruct.new(:a=>1,:b=>2)
=> #

o.instance_variable_get(“@table”)
=> {:a=>1, :b=>2}

T.

On Mar 13, 7:26 am, “Arlen C.” [email protected] wrote:

Hi,

On Thu, Mar 13, 2008 at 7:04 AM, Trans [email protected] wrote:

o = OpenStruct.new(:a=>1,:b=>2)
=> #

o.instance_variable_get(“@table”)
=> {:a=>1, :b=>2}

Looking into internals sounds dangerous. How about -

It may be the only reliable way. Try #dup on an OpenStruct and see
what happens.

T.

Hi,

On Thu, Mar 13, 2008 at 7:04 AM, Trans [email protected] wrote:

o = OpenStruct.new(:a=>1,:b=>2)
=> #

o.instance_variable_get(“@table”)
=> {:a=>1, :b=>2}

Looking into internals sounds dangerous. How about -

a = OpenStruct.new
=> #
a.field = “this”
=> “this”
a.old = “that”
=> “that”
a.methods false
=> [“field=”, “old=”, “field”, “old”]

Arlen

Hi,

On Fri, Mar 14, 2008 at 2:11 AM, Trans [email protected] wrote:

It may be the only reliable way. Try #dup on an OpenStruct and see
what happens.

Very good point. Thank you. I think it’d be good if OpenStruct told us
about
those fields, though. (e.g. by creating the methods on dup)

Arlen

On Mar 13, 6:53 pm, “Arlen C.” [email protected] wrote:

Hi,

On Fri, Mar 14, 2008 at 2:11 AM, Trans [email protected] wrote:

It may be the only reliable way. Try #dup on an OpenStruct and see
what happens.

Very good point. Thank you. I think it’d be good if OpenStruct told us about
those fields, though. (e.g. by creating the methods on dup)

I agree, which is why I created OpenObject (in Facets). OpenObject
will also happily override any built in method, unlike OpenStruct. On
the other hand I was also convinced that a light weight solution is
often all that is needed, so I recently added OpenHash as well. So
that’s another alternative.

T.