[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

OpenStruct,, know what keys are set

warhero

3/10/2007 8:29:00 AM

I need to use an OpenStruct to mimic what an object acts like in another
language. is it possible somehow to find what keys are set on an
OpenStruct at any given time?

thanks

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

15 Answers

David and Sharon Phillips

3/10/2007 9:36:00 AM

0

On 10/03/2007, at 7:29 PM, Aaron Smith wrote:

> I need to use an OpenStruct to mimic what an object acts like in
> another
> language. is it possible somehow to find what keys are set on an
> OpenStruct at any given time?

Disclaimer: I'm fairly new to this, so there's a reasonable chance
I'm wrong to some degree.

Internally, OpenStruct stores the keys as symbols in a hash in an
array @table which can be accessed via marshal_dump.

Alternatively, you may like to add a method like keys_added:

require 'ostruct'

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

person= OpenStruct.new
person.name= "Fred"
person.age= 100

person.keys_added
=> ["age", "name"]




Robert Klemme

3/10/2007 10:44:00 AM

0

On 10.03.2007 10:36, Sharon Phillips wrote:
> On 10/03/2007, at 7:29 PM, Aaron Smith wrote:
>
>> I need to use an OpenStruct to mimic what an object acts like in another
>> language. is it possible somehow to find what keys are set on an
>> OpenStruct at any given time?
>
> Disclaimer: I'm fairly new to this, so there's a reasonable chance I'm
> wrong to some degree.
>
> Internally, OpenStruct stores the keys as symbols in a hash in an array
> @table which can be accessed via marshal_dump.
>
> Alternatively, you may like to add a method like keys_added:
>
> require 'ostruct'
>
> class OpenStruct
> def keys_added
> @table.keys.map{|k| k.to_s}
> end
> end
>
> person= OpenStruct.new
> person.name= "Fred"
> person.age= 100
>
> person.keys_added
> => ["age", "name"]

Yeah, there doesn't seem to be a public method for this. An alternative
approach (btw, I'd stick with symbols as they are more efficient):

irb(main):010:0> o=OpenStruct.new
=> #<OpenStruct>
irb(main):011:0> o.foo=1
=> 1
irb(main):012:0> o.bar=2
=> 2
irb(main):013:0> o.instance_variable_get("@table").keys
=> [:bar, :foo]

OTOH, if you frequently need to get the list of defined members a Hash
is probably a better choice.

Kind regards

robert

Nobuyoshi Nakada

3/10/2007 1:41:00 PM

0

Hi,

At Sat, 10 Mar 2007 17:29:18 +0900,
Aaron Smith wrote in [ruby-talk:242836]:
> I need to use an OpenStruct to mimic what an object acts like in another
> language. is it possible somehow to find what keys are set on an
> OpenStruct at any given time?

o = OpenStruct.new
o.foo = 1
o.bar = 2
p o.methods(false).grep(/[^=]$/) #=> ["bar", "foo"]

--
Nobu Nakada

warhero

3/10/2007 3:53:00 PM

0

Thanks for all the input.

Heres some testing:

require 'ostruct'
require 'benchmark'

lady = OpenStruct.new
0.upto(100) do |i|
eval("lady.cat#{i} = i")
#puts eval("lady.cat#{i}")
end

Benchmark.bm do |x|
x.report("Find all keys 1"){lady.methods(false).grep(/[^=]$/)}
x.report("Find all keys 2"){lady.instance_variable_get("@table").keys}
x.report("Find all keys 3"){lady.keys_added}
end

#puts "\n" + lady.methods(false).grep(/[^=]$/).to_s
#puts "\n" + lady.instance_variable_get("@table").keys.to_s
#puts "\n" + lady.keys_added #this is always nil.


OUTPUT:
user system total real
Find all keys 1 1.130000 0.050000 1.180000 ( 1.185657)
Find all keys 2 0.020000 0.000000 0.020000 ( 0.019773)
Find all keys 3 0.000000 0.000000 0.000000 ( 0.000020)

Results speak for themselves.

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

Robert Klemme

3/10/2007 4:34:00 PM

0

On 10.03.2007 16:53, Aaron Smith wrote:
> Thanks for all the input.
>
> Heres some testing:
>
> require 'ostruct'
> require 'benchmark'
>
> lady = OpenStruct.new
> 0.upto(100) do |i|
> eval("lady.cat#{i} = i")
> #puts eval("lady.cat#{i}")
> end
>
> Benchmark.bm do |x|
> x.report("Find all keys 1"){lady.methods(false).grep(/[^=]$/)}
> x.report("Find all keys 2"){lady.instance_variable_get("@table").keys}
> x.report("Find all keys 3"){lady.keys_added}
> end
>
> #puts "\n" + lady.methods(false).grep(/[^=]$/).to_s
> #puts "\n" + lady.instance_variable_get("@table").keys.to_s
> #puts "\n" + lady.keys_added #this is always nil.
>
>
> OUTPUT:
> user system total real
> Find all keys 1 1.130000 0.050000 1.180000 ( 1.185657)
> Find all keys 2 0.020000 0.000000 0.020000 ( 0.019773)
> Find all keys 3 0.000000 0.000000 0.000000 ( 0.000020)
>
> Results speak for themselves.

Um, for what implementation of "keys_added"? The comment points out
that it always returns nil - I suspect you just measured performance of
an OpenStruct ad hoc getter:

irb(main):005:0> OpenStruct.new.keys_added
=> nil
irb(main):006:0> OpenStruct.new.foo_bar
=> nil

Kind regards

robert

warhero

3/10/2007 4:55:00 PM

0

> Um, for what implementation of "keys_added"? The comment points out
> that it always returns nil - I suspect you just measured performance of
> an OpenStruct ad hoc getter:
>
> irb(main):005:0> OpenStruct.new.keys_added
> => nil
> irb(main):006:0> OpenStruct.new.foo_bar
> => nil
>
> Kind regards
>
> robert

Ah yes, you caught me. I completely overlooked this code in the above
exmaple:
class OpenStruct
def keys_added
@table.keys.map{|k| k.to_s}
end
end


--
New Tests:

require 'ostruct'
require 'benchmark'

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

lady = OpenStruct.new
0.upto(10) do |i|
eval("lady.cat#{i} = i")
#puts eval("lady.cat#{i}")
end

Benchmark.bm do |x|
x.report("Find all keys 1"){lady.methods(false).grep(/[^=]$/)}
x.report("Find all keys 2"){lady.instance_variable_get("@table").keys}
x.report("Find all keys 3"){lady.keys_added}
x.report("Find all keys
4"){lady.instance_variable_get("@table").keys.map{|k| k.to_s }}
end


#puts "\n" + lady.methods(false).grep(/[^=]$/).to_s
#puts "\n" + lady.instance_variable_get("@table").keys.to_s
#puts "\n" + lady.keys_added.to_s
#puts "\n" + lady.instance_variable_get("@table").keys.map{|k| k.to_s
}.to_s


OUTPUT:
user system total real
Find all keys 1 0.000000 0.000000 0.000000 ( 0.000077)
Find all keys 2 0.000000 0.000000 0.000000 ( 0.000014)
Find all keys 3 0.000000 0.000000 0.000000 ( 0.000017)
Find all keys 4 0.000000 0.000000 0.000000 ( 0.000016)

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

Robert Klemme

3/10/2007 10:44:00 PM

0

On 10.03.2007 17:54, Aaron Smith wrote:
>> Um, for what implementation of "keys_added"? The comment points out
>> that it always returns nil - I suspect you just measured performance of
>> an OpenStruct ad hoc getter:
>>
>> irb(main):005:0> OpenStruct.new.keys_added
>> => nil
>> irb(main):006:0> OpenStruct.new.foo_bar
>> => nil
>>
>> Kind regards
>>
>> robert
>
> Ah yes, you caught me. I completely overlooked this code in the above
> exmaple:
> class OpenStruct
> def keys_added
> @table.keys.map{|k| k.to_s}
> end
> end
>
>
> --
> New Tests:
>
> require 'ostruct'
> require 'benchmark'
>
> class OpenStruct
> def keys_added
> @table.keys.map{|k| k.to_s}
> end
> end
>
> lady = OpenStruct.new
> 0.upto(10) do |i|
> eval("lady.cat#{i} = i")
> #puts eval("lady.cat#{i}")
> end
>
> Benchmark.bm do |x|
> x.report("Find all keys 1"){lady.methods(false).grep(/[^=]$/)}
> x.report("Find all keys 2"){lady.instance_variable_get("@table").keys}
> x.report("Find all keys 3"){lady.keys_added}
> x.report("Find all keys
> 4"){lady.instance_variable_get("@table").keys.map{|k| k.to_s }}
> end
>
>
> #puts "\n" + lady.methods(false).grep(/[^=]$/).to_s
> #puts "\n" + lady.instance_variable_get("@table").keys.to_s
> #puts "\n" + lady.keys_added.to_s
> #puts "\n" + lady.instance_variable_get("@table").keys.map{|k| k.to_s
> }.to_s
>
>
> OUTPUT:
> user system total real
> Find all keys 1 0.000000 0.000000 0.000000 ( 0.000077)
> Find all keys 2 0.000000 0.000000 0.000000 ( 0.000014)
> Find all keys 3 0.000000 0.000000 0.000000 ( 0.000017)
> Find all keys 4 0.000000 0.000000 0.000000 ( 0.000016)
>

You should add iterations to the blocks - otherwise the figures are
pretty uninformative. :-) Using bmbm (with rehearsal) might also be a
good idea.

Kind regards

robert

warhero

3/10/2007 11:09:00 PM

0

Robert Klemme wrote:
> On 10.03.2007 17:54, Aaron Smith wrote:
>>>
>>
>> end
>> x.report("Find all keys 3"){lady.keys_added}
>>
>>
>> OUTPUT:
>> user system total real
>> Find all keys 1 0.000000 0.000000 0.000000 ( 0.000077)
>> Find all keys 2 0.000000 0.000000 0.000000 ( 0.000014)
>> Find all keys 3 0.000000 0.000000 0.000000 ( 0.000017)
>> Find all keys 4 0.000000 0.000000 0.000000 ( 0.000016)
>>
>
> You should add iterations to the blocks - otherwise the figures are
> pretty uninformative. :-) Using bmbm (with rehearsal) might also be a
> good idea.
>
> Kind regards
>
> robert

Or if you change the amount of cats the lady has, from 10 to 100000.
then you'll see something more:

lady = OpenStruct.new
0.upto(100000) do |i|
eval("lady.cat#{i} = i")
#puts eval("lady.cat#{i}")
end

i'll add iterations to the blocks as well.

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

Guest

3/12/2007 12:45:00 PM

0

o = OpenStruct.new
o.foo = 2
o.bar = 4
o.marshal_dump # => {:foo=>2, :bar=>4}
o.marshal_dump.keys # => [:foo, :bar]

regards,
Jan

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

warhero

3/12/2007 8:00:00 PM

0

Jan Friedrich wrote:
> o = OpenStruct.new
> o.foo = 2
> o.bar = 4
> o.marshal_dump # => {:foo=>2, :bar=>4}
> o.marshal_dump.keys # => [:foo, :bar]
>
> regards,
> Jan

nice one, that's faster..

require 'ostruct'
require 'benchmark'

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

lady = OpenStruct.new
0.upto(10) do |i|
eval("lady.cat#{i} = i")
#puts eval("lady.cat#{i}")
end

Benchmark.bm do |x|
x.report("Find all keys 1"){
0.upto(100000) do
lady.methods(false).grep(/[^=]$/)
end
}

x.report("Find all keys 2"){
0.upto(100000) do
lady.instance_variable_get("@table").keys
end
}

x.report("Find all keys 3"){
0.upto(100000) do
lady.keys_added
end
}


x.report("Find all keys 4"){
0.upto(100000) do
lady.instance_variable_get("@table").keys.map{|k| k.to_s }
end
}

x.report("Find all keys 5"){
0.upto(100000) do
lady.marshal_dump.keys
end
}
end

user system total real
Find all keys 1 4.110000 0.010000 4.120000 ( 4.151098)
Find all keys 2 0.160000 0.000000 0.160000 ( 0.153028)
Find all keys 3 0.870000 0.010000 0.880000 ( 0.884275)
Find all keys 4 0.900000 0.000000 0.900000 ( 0.897666)
Find all keys 5 0.130000 0.000000 0.130000 ( 0.137231)

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