-
-
Notifications
You must be signed in to change notification settings - Fork 358
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
Support ruby-head/2.8 #1316
Support ruby-head/2.8 #1316
Conversation
We can't use |
1.8.7 doesn't seem to handle kwargs that well:
Let's remove Otherwise, good job, I believe it's the way to go. You might be interested in this approach to maintain support for both Ruby 1.8.7 and 2.8+. |
RSpec::Mocks.space.any_instance_recorders_from_ancestry_of(object).each do |subscriber| | ||
subscriber.notify_received_message(object, message, args, block) |
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.
Wondering if we can pass block as &block
and get rid of _block
parameter in the notify_received_message
method signature.
def message_received(message, *args, &block) | ||
record_message_received message, *args, &block | ||
def message_received(message, *args, **opts, &block) | ||
Byebug.byebug |
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.
Leftover.
RSpec::Mocks.space.any_instance_recorders_from_ancestry_of(object).each do |subscriber| | ||
subscriber.notify_received_message(object, message, args, block) | ||
subscriber.notify_received_message(object, message, args, opts, block) |
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.
Maybe pass it as *args, **opts
here as well?
@pirj, 1.8.7 does not support |
That's what I've tried to point out in a gentle manner :D |
Is there an ETA for this? I imagine many more projects would be interested in rspec supporting ruby 2.8 than 1.8. |
Sorry, we're all volunteers no ETAs. Its more of a Ruby 2.7 support issue at the moment as thats a released version of Ruby. Ruby 2.8 will be supported when its released which is traditionally in December and by then I hope to have a new major release of RSpec dropping older Ruby support. |
Well, you also have volunteers offering to contribute ruby 2.8 support (I'm not the only one from what I am gathering) but what you are saying - correct me if I'm wrong - is this work is not wanted because you wish to support long-EOLed ruby 1.8/1.9. For us (Ruby driver for MongoDB and Mongoid) lack of Ruby 2.8 support in rspec is effectively a regression - we test all projects on ruby-head and as of Ruby 2.7 release the ruby-head tests are failing because of rspec. |
Not at all, it just needs to support ruby 1.8 and 1.9 too if you'd like it merged into master / released. |
I am open to doing a reasonable amount of work to achieve that. If https://github.com/rspec/rspec-support/pull/394/files#diff-6f77530d5756f8c02ca078ddecaa891cL120 is the suggested approach, what this looks like to me is is replacing every one line of code with 10 lines of eval with code duplicated and a major loss of readability. Given the number of lines affected (this PR is only a part of the full change set) I think this is not a realistic approach. |
I'm open to an improved approach, the difficulty is that older rubies cannot even parse Speaking as the author of the diff you've highlighted I accept that it may look less directly readable due to the string eval (I'm personally ok with it because it has no directly eval'd parts, its literally the code that would exist if it could be parsed by Ruby), but the conditional code definition (its not duplication, the methods are different implementation) is something we do all the time in RSpec because it is much more performant than the alternative of using if at runtime. |
Is my assessment that 1 line of existing code will be replaced by 10 lines of 1.8+2.8 compatible code correct? If yes, can the 10 lines be programmatically generated from 1 line (potentially a revised one)? If so I would say this is a smarter path to pursue than writing 1000-2000 lines of code now (based on this PR being +35 -35, and being incomplete) which will need to be removed in a year. If the 10 lines of code cannot be programmatically generated (i.e. they have important differences) I doubt writing them by hand and getting them right is something I personally see myself doing. I think it will be much less effort overall to a version like 3.9 to be a "long term support" one which ruby 1.8/1.9 projects can use, with bug fixes only. I suspect there aren't too many bugs reported against 3.x branch of rspec after 9 minor releases? rspec 3.10 can then require ruby 2.0. |
No it's not, what happened was the original implementation was inlined then wrapped in an
I did it in vim so, probably, except for the new code addition a vim macro could quite easily add the if and conditional case the old code allowing you to concentrate then on the code you wish to change.
It wont be thousands of lines of code, its just a few, you likely have most of them in this PR, most of RSpec does not need keyword argument support in this fashion because we don't use keyword arguments except for supporting user code in mock definitions.
Semantic versioning requires us to support all the older rubies until RSpec 4. There isn't likely to be a 3.10. |
OK, in this case would you mind taking one/a few of the hunks in this PR and altering it to be functionally correct and mergeable?
What I meant was, the source code would contain 1 line. This line will either be expanded at runtime or in some kind of a pre-processing transformation but if one needs to make changes to that line in the future they would be working with this 1 line instead of the expanded 10 lines. |
I'll see if I can find time later in the week, it's late here and I have a busy work schedule tomorrow.
That sounds overly complicated, as indicated we prefer solutions that are implemented at parse time so that user performance isn't effected. In practise we've never needed to modify the fallback "old code" because its worked for so long previously, it tends to be the new solutions which introduce bugs. |
Volunteers are always welcome! You seem to have experience with
Does it look like a reasonable approach to you?
I've checked some of the recent builds, jobs are green except
I apologise in advance for not checking further builds for failure reasons, and I completely understand your point that lack of proper
Keeping in mind your tight schedule and lack of even formal ETA this raises the risks of not being it ready by the moment Ruby 2.8 is released in December. Leaving it up to you to decide what is a reasonable amount of work that you would like to dedicate to improve or completely fix RSpec support for
Do you have some examples of such generator/pre-processing, preferably for real code, ideally in this pull request? I'd really love to see this in action, might be the most viable approach to the problem. |
It seems fine to me but https://github.com/ruby/ruby2_keywords does not explain much as far as what it does, when one would use it, what the caveats are, etc. If it works I say it's a fine solution.
These are fixed in mongodb/mongoid#4720. The current build log is https://evergreen.mongodb.com/task_log_raw/mongoid_rubies__mongodb_version~4.0_topology~replica_set_ruby~ruby_head_driver~current_test_patch_044e3c9751851638ef4a85a845fc16ecb82831b3_5e28c5f83627e075e55518da_20_01_22_22_00_37/0?type=T, in which the first 5 failures are caused by the issue described in this PR. I don't know if the subsequent failures are issues in Mongoid that are yet to be addressed or failures resulting from the first 5 failures in some way.
No, this was just a general remark that in Ruby I typically do not expect to type out a lot of boilerplate. I use Ruby because it is a concise language.
I had another thought as to how to fix the overall problem. I figure most methods changed in this PR are internal to rspec and thus don't need to use **opts syntax - they can pass opts as an argument. The only methods that must deal with keyword arguments are the opposite ends of the entire stack (the method called by applications and the method in rspec that ultimately invokes original implementation). So, the awkwardness may only need to exist in a relatively small number of places. On the topic of 1.8/1.9 support, we stopped supporting them in part because building those rubies seems to be running into problems with current openssl releases. Which modern linux distributions do 1.8/1.9 build on out of the box? |
It's fine with me. |
Anywhere we defined the method, we should be able to add |
#1324 is currently warning free on |
ruby-head does not pass keyword arguments, making this test fail:
Proposed solution is to take *args and **opts separately in all methods.