From: Dan Rathbun Date: 2010-03-17T05:39:20+09:00 Subject: [ruby-core:28699] [Feature #1400] Please add a method to enumerate fields in OpenStruct Issue #1400 has been updated by Dan Rathbun. This can be done right now. In several ways. # obj is an class OpenStruct which some number of members. ary = obj.methods(false).sort -> Array of attr getters and setters keys=[] ary.each {|i| keys.push(i) unless i.include?('=') } # keys is now an Array of fieldnames Also using existing method .marshal_dump which is really an attribute getter for @table (having a name different than the attribute.) Just noticed .table as a attribute getter alias of .marshal_dump, BUT .table is set protected, while .marshal_dump is not? Why is THAT? # obj is an class OpenStruct which some number of members. obj.marshal_dump.keys -> Array of keys obj.marshal_dump.values -> Array of values obj.marshal_dump.each {|k,v| ... } The danger in accessing the Hash directly is someone's going to modify it without removing the attr getter and setter methods defined in the class instance. Which by the way is a bug in the current OpenStruct. It's delete_field method does just that, leaving the accessor methods without a key/value pair in @table. There is also an opposite bug. IF an attempt is made, to create a field who's name is already used as a method (without the '='); new_ostruct_member does NOT create the accessor methods, BUT does NOT return a indicator of success, so method_missing just goes ahead and adds the field to @table. Ex: obj.inspect='Sherlock Holmes' The unless block (line 72) in new_ostruct_member needs an else clause thats raises a NameError Exception "#{name} is already in use as a method of #{self}." Additionally, .marshal_load is flawed. It wipes out @table instead of appending; and puts everything in @table before checking it. The arg x should be typechecked as an OpenStruct or Hash; it should be put first in a temp reference. Looks like another argument may be needed for overwrite/ignore of matching keys. ---------------------------------------- http://redmine.ruby-lang.org/issues/show/1400 ---------------------------------------- http://redmine.ruby-lang.org