[#100309] How to use backport custom field — Jun Aruga <jaruga@...>
Please allow my ignorance.
9 messages
2020/10/06
[#100310] Re: How to use backport custom field
— "NARUSE, Yui" <naruse@...>
2020/10/06
"Backport custom field" is only available for tickets whose tracker is "Bug".
[#100311] Re: How to use backport custom field
— Jun Aruga <jaruga@...>
2020/10/06
On Tue, Oct 6, 2020 at 4:44 PM NARUSE, Yui <naruse@airemix.jp> wrote:
[#100314] Re: How to use backport custom field
— "NARUSE, Yui" <naruse@...>
2020/10/06
Thank you for confirmation.
[#100322] Re: How to use backport custom field
— Jun Aruga <jaruga@...>
2020/10/07
On Tue, Oct 6, 2020 at 7:25 PM NARUSE, Yui <naruse@airemix.jp> wrote:
[#100326] Re: How to use backport custom field
— "NARUSE, Yui" <naruse@...>
2020/10/07
I added you to "Reporter" role in the project
[#100327] Re: How to use backport custom field
— Jun Aruga <jaruga@...>
2020/10/07
On Wed, Oct 7, 2020 at 1:42 PM NARUSE, Yui <naruse@airemix.jp> wrote:
[#100358] [BUG] ruby 2.6.6 warning with encdb.so — shiftag <shiftag@...>
Hello,
1 message
2020/10/10
[ruby-core:100500] [Ruby master Feature#16461] Proc#using
From:
eregontp@...
Date:
2020-10-22 10:58:02 UTC
List:
ruby-core #100500
Issue #16461 has been updated by Eregon (Benoit Daloze).
Reading #12086 again, I feel #12281 is a much simpler alternative (`using(refinement) { literal block }`).
Wouldn't #12281 be enough?
`block.using(IntegerDivExt)` is mutating state and this feels too magic and dangerous to me.
I think DSL users can accept to wrap their DSL code with `using(refinement) { ... }` (or `using refinement` in a module/file).
That's actually not more verbose than `using Proc::Refinements` and I think so much clearer.
We could have additional requirements to ensure it's truly lexical and the `refinement` given to a given `using(refinement) { ... }` call site is always the same.
I think that would be good, because then we know code inside always use the given refinements, much like how `using refinement` works today.
For the `User.where { :age > 3 }` case, if we want to avoid an extra `using(refinement) { ... }`, I think it could be fine to automatically enable refinements *if* we can ensure it's still fully lexical.
Concretely that would mean for that block `{ :age > 3 }` it's always called with the same refinements, no matter where it's called from.
Attempting to use any other refinement would raise an error.
Maybe a way to design this restriction could be to annotate the method `where` with "enables MyRefinement on the lexical block given to it".
```ruby
class ModelClassMethods
def where(&block)
...
block.call / yield
end
instance_method(:where).use_refinements_for_block(ActiveRecord::WhereDSL)
end
User.where { :age > 3 }
```
That way I think we can ensure the given literal block always has the exact same refinements.
Multiple `use_refinements_for_block` calls for a method would be an error.
And `use_refinements_for_block` should be used before the method is called (so there is no block before executed without refinements).
Implementation-wise, `where` would modify the refinements for the block/Proc, before executing the body of `where`, so it would all be transparent to the user.
----------------------------------------
Feature #16461: Proc#using
https://bugs.ruby-lang.org/issues/16461#change-88120
* Author: shugo (Shugo Maeda)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version: 3.0
----------------------------------------
## Overview
I propose Proc#using to support block-level refinements.
```ruby
module IntegerDivExt
refine Integer do
def /(other)
quo(other)
end
end
end
def instance_eval_with_integer_div_ext(obj, &block)
block.using(IntegerDivExt) # using IntegerDivExt in the block represented by the Proc object
obj.instance_eval(&block)
end
# necessary where blocks are defined (not where Proc#using is called)
using Proc::Refinements
p 1 / 2 #=> 0
instance_eval_with_integer_div_ext(1) do
p self / 2 #=> (1/2)
end
p 1 / 2 #=> 0
```
## PoC implementation
For CRuby: https://github.com/shugo/ruby/pull/2
For JRuby: https://github.com/shugo/jruby/pull/1
## Background
I proposed [Feature #12086: using: option for instance_eval etc.](https://bugs.ruby-lang.org/issues/12086) before, but it has problems:
* Thread safety: The same block can be invoked with different refinements in multiple threads, so it's hard to implement method caching.
* _exec family support: {instance,class,module}_exec cannot be supported.
* Implicit use of refinements: every blocks can be used with refinements, so there was implementation difficulty in JRuby and it has usability issue in headius's opinion.
## Solutions in this proposal
### Thread safety
Proc#using affects the block represented by the Proc object, neither the specific Proc object nor the specific block invocation.
Method calls in a block are resolved with refinements which are used by Proc#using in the block at the time.
Once all possible refinements are used in the block, there is no need to invalidate method cache anymore.
See [these tests](https://github.com/shugo/ruby/pull/2/commits/1c922614ad7d1fb43b73e195348c81da7a4546ef) to understand how it works.
Which refinements are used is depending on the order of Proc#using invocations until all Proc#using calls are finished, but eventually method calls in a block are resolved with the same refinements.
### * _exec family support
[Feature #12086](https://bugs.ruby-lang.org/issues/12086) was an extension of _eval family, so it cannot be used with _exec family, but Proc#using is independent from _eval family, and can be used with _exec family:
```ruby
def instance_exec_with_integer_div_ext(obj, *args, &block)
block.using(IntegerDivExt)
obj.instance_exec(*args, &block)
end
using Proc::Refinements
p 1 / 2 #=> 0
instance_exec_with_integer_div_ext(1, 2) do |other|
p self / other #=> (1/2)
end
p 1 / 2 #=> 0
```
### Implicit use of refinements
Proc#using can be used only if `using Proc::Refinements` is called in the scope of the block represented by the Proc object.
Otherwise, a RuntimeError is raised.
There are two reasons:
* JRuby creates a special CallSite for refinements at compile-time only when `using` is called at the scope.
* When reading programs, it may help understanding behavior. IMHO, it may be unnecessary if libraries which uses Proc#using are well documented.
`Proc::Refinements` is a dummy module, and has no actual refinements.
--
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>