From: abhilashmv@... Date: 2018-10-16T05:07:43+00:00 Subject: [ruby-core:89412] [Ruby trunk Feature#15225] OpenStruct: Recursively converting child Hash objects to OpenStruct objects. Issue #15225 has been updated by abhionlyone (Abhilash Reddy). shevegen (Robert A. Heiler) wrote: > This is an interesting suggestion. > > I actually implemented something similar for a class that I tend to call Configuration. > > This class also allows for using its keys as method names, so I can relate to your > suggestion here. (If you are curious, class Configuration usually reads .yml files > from a configuration directory, and then enables/disables certain functionality > and information on a per-project basis). > > On the other hand, I am not sure if this should be the (new) default for OpenStruct, > despite feeling that it may be useful. Perhaps something of a toggle way, to allow > a variant of OpenStruct that responds to methods as you describe, without changing > the status quo of OpenStruct's behaviour (You should also define the behaviour what > happens when a key is removed again; will the method remain or be removed as well? > Or just return nil but remain there?) > > I myself probably do not need it, primarily because I rarely use Struct/OpenStruct; > and for keys-as-methods, I already use specialized classes such as my custom > class Configuration (although I have this for my colour-class too, where I can > simply use .slateblue() or .royalgreen() etc... to make use of the "HTML web-colours"), > yet I can see that this may be useful for other people too, so it may be worthwhile > to think about it (that is of course my personal opinion; at the end of the day you only > have to convince matz). > > I think we could actually decouple your suggestion, away from OpenStruct, to a more > general question: > > **Should core-ruby allow for a class or a pattern that allows for keys in a key-value > pair (a hash) to be used/usable as method calls?** I can not answer this question really > but I think it is worth to have a deeper look at it. > > Last but not least, I would encourage a little patience in regards to the proposal, mostly > so that other people can also comment on the usefulness of the underyling pattern > (even though your suggestion is solely about OpenStruct, I think the idea and intent > behind the suggestion can also be asked more generally). > > Having this as the new default may be somewhat difficult though, as the path towards > ruby 3.x will probably not have too many incompatibilities (e. g. as opposed to the > full transition from ruby 1.8.x to 2.x) - but again, that is only my own perception, I > have been very wrong before. :) Thanks for taking the time to review this feature request. If possible please take a look at this PR https://github.com/ruby/ostruct/pull/5/files. I'm really sorry that I've not explained what I'm trying to do in a proper manner. ~~~ ruby person = Person.new({name: "Abhilash", more_info: {country: "JAPAN", skills: ["Ruby", "C++"]}}) puts person.more_info # This will be still a Hash person = Person.new({name: "Abhilash", more_info: {country: "JAPAN", skills: ["Ruby", "C++"]}}, true) puts person.more_info # Now this will be a OpenStruct object ~~~ So unless you explicitly pass **true** to the OpenStruct constructor, The child Hash Objects will never be converted to OpenStruct objects. So, This will not create any compatibility issues for the existing code. ---------------------------------------- Feature #15225: OpenStruct: Recursively converting child Hash objects to OpenStruct objects. https://bugs.ruby-lang.org/issues/15225#change-74452 * Author: abhionlyone (Abhilash Reddy) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- Currently, OpenStruct allows this: ~~~ ruby person = OpenStruct.new person.age = 25 person.name = "Abhilash" puts person.name # "Abhilash" ~~~ But something like this is not possible: ~~~ ruby person.more_info = {country: "Japan", skills: ["Ruby", "C++"]} puts person.more_info.country # NoMethodError (undefined method `country' for {:country=>"Japan"}:Hash) ~~~ It will be very helpful if we can provide an option to recursively convert child Hash objects to OpenStruct objects. By default it can be set to false. I've done a basic implementation of this and created a PR here: https://github.com/ruby/ostruct/pull/5 Please let me know if there are any objections. If this can be accepted, I would like to add test cases for the same. -- https://bugs.ruby-lang.org/ Unsubscribe: