[#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
IkJhY2twb3J0IGN1c3RvbSBmaWVsZCIgaXMgb25seSBhdmFpbGFibGUgZm9yIHRpY2tldHMgd2hv
[#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 <[email protected]> wrote:
[#100314] Re: How to use backport custom field
— "NARUSE, Yui" <naruse@...>
2020/10/06
VGhhbmsgeW91IGZvciBjb25maXJtYXRpb24uCkkgY2hlY2tlZCBhZ2FpbiBhbmQgdG8gZWRpdCBi
[#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 <[email protected]> wrote:
[#100326] Re: How to use backport custom field
— "NARUSE, Yui" <naruse@...>
2020/10/07
SSBhZGRlZCB5b3UgdG8gIlJlcG9ydGVyIiByb2xlIGluIHRoZSBwcm9qZWN0CgoyMDIw5bm0MTDm
[#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 <[email protected]> wrote:
[ruby-core:100538] [Ruby master Bug#17159] extend `define_method` for Ractor
From:
marcandre-ruby-core@...
Date:
2020-10-25 20:08:18 UTC
List:
ruby-core #100538
Issue #17159 has been updated by marcandre (Marc-Andre Lafortune).
How about:
```ruby
define_method(:name, make_shareable: true) { ... }
# equivalent to:
define_method(:name, &Ractor.make_shareable(Proc.new{...}))`
```
With `make_shareable` as making accessed external variables shareable and not reassignable.
----------------------------------------
Bug #17159: extend `define_method` for Ractor
https://bugs.ruby-lang.org/issues/17159#change-88166
* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
* Backport: 2.5: DONTNEED, 2.6: DONTNEED, 2.7: DONTNEED
----------------------------------------
Ractor prohibits use of non-isolated `Proc`s.
Non-isolated example is here:
```ruby
s = "foo"
pr = Proc.new{ p s }
```
This Proc `pr` can not be shared among ractors because outer variable `s` can contain an unshareable object. Also outer binding is a mutable object. Sharing it can lead race conditions.
Because of these reasons, `define_method` is also a problem on a multi-Ractor program.
(current implementation allows it just because check is not implemented, and it leads BUG).
I think there are several patterns when `define_method` is needed.
(1) To choose method names on-the-fly
```ruby
name = ...
define_method(name){ nil }
```
(2) To embed variables to the code
```ruby
10.times{|i|
define_method("foo#{i}"){ i }
}
```
(3) To use global state by local variables
```ruby
cnt = 0
define_method("inc"){ cnt += 1 }
```
(4) Others I can't imagine
----
(1) is easy. We can allow `define_method(name, &Proc{nil}.isolate)`.
(3) can never be OK. It introduces data races/race conditions. For this purpose one need to use shared hash.
```ruby
STATE = SharedHash.new(cnt: 0)
define_method("inc"){ STATE.transaction{ STATE[:cnt] += 1 }}
```
I think there are many (2) patterns that should be saved.
To help (2) pattern, the easiest way is to use `eval`.
```ruby
10.times{|i|
eval("def foo#{i} #{i}; end")
}
```
However, `eval` has several issues (it has huge freedom to explode the program, editor's syntax highlighting and so on).
Another approach is to embed the current value to the code, like this:
```ruby
i = 0
define_method("foo", ractorise: true){ i }
#=> equivalent to:
# define_method("foo"){ 0 }
# so that if outer scope's i changed, not affected.
i = 1
foo #=> 0
s = ""
define_method("bar", ractorise: true){ s }
#=> equivalent to:
# define_method("bar"){ "" }
# so that if outer scope's s or s's value, it doesn't affect
s << "x"
bar #=> ""
```
However, it is very differenct from current Proc semantics.
Another idea is to specify embedding value like this:
```ruby
i = 0
define_method("foo", i: i){ i }
#=> equivalent to:
# define_method("foo"){ 0 }
# so that if outer scope's i changed, not affected.
i = 1
foo #=> 0
s = ""
define_method("bar", s: s){ s }
#=> equivalent to:
# define_method("bar"){ "" }
# so that if outer scope's s or s's value, it doesn't affect
s << "x"
bar #=> ""
```
`i: i` and `s: s` are redundant. However, if there are no outer variable `i` or `s`, the `i` and `s` in blocks are compiled to `send(:i)` or `send(:s)`. But I agree these method invocation should be replaced is another idea.
Thoughts?
Thanks,
Koichi
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>