Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

joerixaop
Copy link
Contributor

On JRuby 9.3 the fix from #513 does not work, because the modifiable method has disappeared.

On JRuby 9.2 replacing modifiable[new_ostruct_member!(mname)]= with self[mname]= is not a problem as the existing implementation of #[]= takes care of both checking that it's still modifiable and calling new_ostruct_member!.

joerixaop added 2 commits July 6, 2022 11:17
I believe this doesn't change any behaviour on either version (although
weird behaviour may exist when users set keys with string values
explicitly).
On JRuby 9.3 new_ostruct_member! checks if it already knows a new key by
checking the `@table` instance variable, before checking whether a
method is already defined (I assume because it's faster in the common
case), the way `@table` is handled with auto-vivifying values made this
not work properly for nested assignments.

E.g. `config.webxml.rails.env = 'production'` would auto-vivify
config.webxml.rails without defining a singleton method.

On JRuby 9.3 we could scrap method_missing, it has the right behaviour
(i.e. the workaround for jruby#366 added in 9245f4c is no longer
required). Unfortunately it's still required on JRuby 9.2
@JesseChavez
Copy link
Contributor

Looking deeper in the open struct code the current method_missing, the implementation of in warbler is copy and paste from and older version of open struct.

https://github.com/ruby/ostruct/blob/1ea1438e592b7407654d0ead49f3a20f813a44cc/lib/ostruct.rb#L175

does it work by removing method_missing and using the original implementation ?

@joerixaop
Copy link
Contributor Author

The answer is that this does work for 9.3, but not for 9.2, because the version of ostruct used in 9.2.21 will check that a key is present in the table in it's method_missing implementation with if @table.key?(mid) and return nil if it is not in there, so with that implementation of method_missing you need to assign a key before it checks the table.

It's in particular the changes in jruby/jruby@d6f4cc1 , which seem to be included in every version from 9.1 up to (but not including) 9.3, so we can't drop the implementation of method_missing.

For the moment I went with the approach that required the least changes to the code., but the right approach probably is to not use OpenStruct. OpenStruct doesn't seem to fit the purpose of the class entirely (not allowing for nested assignments) and from Jruby 9.3 onwards I expect the ostruct code to be updated more frequently as it's now included through pom.xml instead of through direct inclusion of the code.

@olleolleolle
Copy link
Member

@joerixaop Thanks for the carefully added context to the PR description and for the fix & analysis.

(Thanks, @deivid-rodriguez for review!)

@olleolleolle olleolleolle merged commit ef819a7 into jruby:master Aug 9, 2022
@chadlwilson chadlwilson added this to the 2.1.0 milestone Oct 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants