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

Skip to content

def_*_delegator from v1.3.0 does not return name of delegator method in Ruby 2.6 and older #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ashmaroli opened this issue Dec 2, 2019 · 2 comments

Comments

@ashmaroli
Copy link

In v1.2.0, def_delegator :@obj, :data, :fallback_data would return :fallback_data but v1.3.0 just returns nil

The cause for this is the last expression mod.send(:ruby2_keywords, ali) if RUBY_VERSION >= '2.7' in the following definition:

def def_instance_delegator(accessor, method, ali = method)
gen = Forwardable._delegator_method(self, accessor, method, ali)
# If it's not a class or module, it's an instance
mod = Module === self ? self : singleton_class
mod.module_eval(&gen)
mod.send(:ruby2_keywords, ali) if RUBY_VERSION >= '2.7'
end

The last expression is evaluated only if RUBY_VERSION >= '2.7'.
The preferred solution would be to stash the result of the previous expression and return that stashed value for Ruby 2.6 and older:

 def def_instance_delegator(accessor, method, ali = method)
   gen = Forwardable._delegator_method(self, accessor, method, ali)

   # If it's not a class or module, it's an instance
   mod = Module === self ? self : singleton_class

   # stash in a lvar
   result = mod.module_eval(&gen)
   RUBY_VERSION >= '2.7' ? mod.send(:ruby2_keywords, ali) : result
 end

Based on the diff of #5, this issue would affect :single_delegator as well.

/cc @jeremyevans @hsbt Requesting a patch to be shipped at the earliest.
Thank you.

@jeremyevans
Copy link
Contributor

The return value of def_instance_delegator and def_single_delegator is not specified in the documentation or tested by any specs. Therefore, any code that depends on the return value of the methods is relying on undefined behavior.

That being said, I am not opposed to putting out a 1.3.1 that restores the previous behavior and adds documentation and specs for it. I'll submit a pull request later today, and hopefully @hsbt can handle the release.

In the future, please use a more accurate subject. 1.3.0 isn't broken, it works for almost all cases. That the undefined behavior in 1.3.0 differs from previous undefined behavior, and it caused a problem in a widely-used application is unfortunate, but no reason for hyperbole.

@ashmaroli ashmaroli changed the title v1.3.0 is broken def_*_delegator from v1.3.0 does not return name of delegator method in Ruby 2.6 and older Dec 2, 2019
@ashmaroli
Copy link
Author

ashmaroli commented Dec 2, 2019

@jeremyevans Thank you for responding.
I apologize for the hyperbolic title of this ticket. I couldn't come up with an apt one at the time.
I've now renamed it by taking a cue from your patch's commit message.

I was not aware that the usage I was familiar with is an undocumented behavior that shouldn't be considered as public API. Moving forward, what would be the best way to conform to this module's Public API yet maintain the downstream's current behavior?

@hsbt hsbt closed this as completed in a52ef34 Dec 11, 2019
hsbt added a commit that referenced this issue Dec 11, 2019
Make def_*_delegator return name of method defined (Fixes #10)
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

No branches or pull requests

2 participants