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: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>