-
-
Notifications
You must be signed in to change notification settings - Fork 354
Replace string eval #340
Replace string eval #340
Conversation
In the majority of instances, using define_method over eval'ing a String is better, and safer. See: http://tenderlovemaking.com/2013/03/03/dynamic_method_definitions.html
These two methods are particularly tricky in their use of string
interpolation for the `class_eval`. To remove the string passed to
`class_eval` one of two approaches is possible:
* Retain the `class_eval` and exploit the block closure by defining
local variables referencing the instance variables to be used in the
eval block
* Switch to using `class_exec` which was introduced in 1.8.7 and 1.9.
This allows for instance variables to be passed into the block
creating block local variables
I choose the latter for writing cleaner code and to embrace the future
dropping of support for 1.8.6.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cupakromer thanks for this PR! I don't get why this raise_error got more specific in something related to changing evals to define_method type situations. What's going on here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was some interpolation going on in https://github.com/rspec/rspec-mocks/pull/340/files#L4R16. Without the more specific spec, I wasn't sure if my change to the method_name interpolation was correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the drop of the .inspect call I'm ok with this change to the spec
Breaking 1.8.6 support is fine in master. We're dropping support in RSpec 3.0. As for the |
Remove the instances where `class_eval` is there only to change the value of `self` for the `define_method` message. Just send it directly to the desired object. Use `__send__` as `define_method` is private. Remove the superfluous instances of `to_syms`.
|
(Sorry repeating from line comment in case it gets lost) We've already dropped support for 1.8.6 and even 2.14 doesn't work 100% with it so I don't think it's an issue with respect to this. I'm leaning towards preferring |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the to_sym necessary here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Nope, your'e right. I now see it was necessary in the original due to the string interpolation (symbols are converted to strings), so the colon needed to be added back. Will remove.
|
Good work, I thought I'd caught most of these on my first pass through removing evals, guess not :) ❤️ ❤️ ❤️ |
First pass at replacing all uses of string eval per #267
I've tested on 1.8.7-p374, 1.9.3-p392, and 2.0.0-p247.
One potential issue is that I made the decision to use
Module#class_execwhich was only added in 1.8.7 and 1.9. I did this for two reasons:This will break 1.8.6 support. Let me know what you think.