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-forum.com/.
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-forum.com/.
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"]
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?
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
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-forum.com/.
a little late to the party but in any case...
require 'facets/core/ostruct/instance_delegate'
OpenStruct.new(:a=>1,:b=>2).instance_delegate.keys #=> [ :a, :b ]
T.
On Mar 10, 4:29 am, Aaron Smith <beingthexempl...@gmail.com> 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?thanks
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
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
endperson= OpenStruct.new
person.name= "Fred"
person.age= 100person.keys_added
=> ["age", "name"]
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-forum.com/.
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-forum.com/\.
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
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}")
endBenchmark.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.
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,
Jannice one, that's faster..
marshal_dump returns @table, so marshal_dump.keys == @table.keys except that @table is not accessable from outside OpenStruct.
http://www.ruby-doc.org/stdlib/libdoc/ostruct/rdoc/classes/OpenStruct.html
Click on the [Source] link to see the code behind these methods.
Note that some of your examples here return symbols (2 and 5) whilst 3 and 4 take an extra step of transforming these into strings.
Looks like you're having fun
Dave
On 13/03/2007, at 6:59 AM, Aaron Smith wrote:
require 'ostruct'
require 'benchmark'class OpenStruct
def keys_added
@table.keys.map{|k| k.to_s}
end
endlady = OpenStruct.new
0.upto(10) do |i|
eval("lady.cat#{i} = i")
#puts eval("lady.cat#{i}")
endBenchmark.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
}
enduser 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-forum.com/\.
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
=> nilKind 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-forum.com/\.
Sharon Phillips wrote:
On 13/03/2007, at 6:59 AM, Aaron Smith wrote:
nice one, that's faster..
marshal_dump returns @table, so marshal_dump.keys == @table.keys
except that @table is not accessable from outside OpenStruct.
http://www.ruby-doc.org/stdlib/libdoc/ostruct/rdoc/classes/
OpenStruct.html
Click on the [Source] link to see the code behind these methods.Note that some of your examples here return symbols (2 and 5) whilst
3 and 4 take an extra step of transforming these into strings.Looks like you're having fun
Dave
Hey Dave, thanks,
yes I love ruby. I've never had so much fun with a programming language.
It didn't even occur to me I have k.to_s in example 4. I appreciate
you're input.
-a
--
Posted via http://www.ruby-forum.com/\.
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
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
=> nilKind 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
endlady = OpenStruct.new
0.upto(10) do |i|
eval("lady.cat#{i} = i")
#puts eval("lady.cat#{i}")
endBenchmark.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_sOUTPUT:
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)
Robert Klemme 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.