Issue #18899 has been updated by Dan0042 (Daniel DeLorme).
Naively, I would have expected "binary:utf-8" to take arbitrary input and force the encoding to UTF-8, and "utf-8:utf-8" to read and validate the input as UTF-8.
Neither does what I expected. `¯\_(ツ)_/¯`
----------------------------------------
Bug #18899: Inconsistent argument handling in IO#set_encoding
https://bugs.ruby-lang.org/issues/18899#change-100360
* Author: javanthropus (Jeremy Bopp)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
`IO#set_encoding` behaves differently when processing a single String argument than it does when processing 2 arguments (whether Strings or Encodings) in the case where the external encoding is being set to binary and the internal encoding is being set to any other encoding.
This script demonstrates the resulting values of the external and internal encodings for an IO instance given different ways to equivalently call `#set_encoding`:
```ruby
#!/usr/bin/env ruby
def show(io, args)
printf(
"args: %-50s external encoding: %-25s internal encoding: %-25s\n",
args.inspect,
io.external_encoding.inspect,
io.internal_encoding.inspect
)
end
File.open('/dev/null') do |f|
args = ['binary:utf-8']
f.set_encoding(*args)
show(f, args)
args = ['binary', 'utf-8']
f.set_encoding(*args)
show(f, args)
args = [Encoding.find('binary'), Encoding.find('utf-8')]
f.set_encoding(*args)
show(f, args)
end
```
This behavior is the same from Ruby 2.7.0 to 3.1.2.
--
https://bugs.ruby-lang.org/
Issue #19099 has been updated by Dan0042 (Daniel DeLorme).
Another idea:
`private_constant X: expr`
equivalent to
`const_set :X, expr` + `private_constant :X`
----------------------------------------
Feature #19099: Support `private_constant` for an undefined constant
https://bugs.ruby-lang.org/issues/19099#change-100359
* Author: ujihisa (Tatsuhiro Ujihisa)
* Status: Open
* Priority: Normal
----------------------------------------
All the following discussion applies to `public_constant` too. Maybe `deprecate_constant` as well.
## Problem
```ruby
class C
X = ...
private_constant :X
end
```
The above idiom usually works fine, but when `...` part is long, like a 30-line Ruby Hash, it's very easy to miss the following `private_constant :X` part.
## Impossible solution
```ruby
class C
private_constant X = ...
end
```
Like `private`, if the above notation could work, it would be awesome, but it breaks so many backward compatibility. The constant assignment returns its value but not the name of the constant, and we should keep the current behaviour.
## Proposed solution
Allow the following new notation for `private_constant` by making constant private by name without actually resolving itself and raises an error.
``` ruby
class C
private_constant :X
X = ...
end
```
The current behaviour is to raise NameError.
```
/tmp/v8svpb4/95:2:in `private_constant': constant C::X1 not defined (NameError)
private_constant :X1
^^^^^^^^^^^^^^^^
from /tmp/v8svpb4/95:2:in `<class:C>'
from /tmp/v8svpb4/95:1:in `<main>'
```
This proposal breaks this backward compatibility.
Also I'm concerned about potential typos. It may be hard to find typos.
```ruby
class C
private_constant :BEHAVIOUR
BEHAVIOR = 123 # Remains public unintentionally
end
```
Maybe we need some sort of foolproof somewhere in this way.
--
https://bugs.ruby-lang.org/
Issue #19078 has been updated by Dan0042 (Daniel DeLorme).
Maybe I'm too late here, but I have some thoughts/concerns about this.
First I should say I totally agree with the general idea. We need some way to inherit "context state".
So far I've seen 2 use cases described.
1 - store a request_id or correlation_id, for logging purposes (or even the full request object)
2 - store a connection (typically database) that can't be used at the same time by another thread/fiber
It would be nice if we had 1-2 other use cases; that would allow to evaluate this design from more angles.
We already have per-thread-but-actually-fiber storage, and a really-per-thread storage, and this is adding a third type. What about when we want per-ractor storage... a fourth type? Per-ractor inheritable storage... a fifth type? Rather than fragmenting storages I would prefer to unify them. Maybe it's a crazy idea, but what if we set fiber-inheritable values via `Thread.current.store(k, v, level: Fiber, inherit: true)` and read them via `Thread.current[k]` ? For writing it's a somewhat complex/advanced interface, but choosing which storage to use is a complex/advanced question anyway. And when reading a value I think we typically don't care about which storage it is in; it would be easier to have a single point of access.
When should a value be inherited? For usecase#1 (request_id), it seems to be all the time. But for usecase#2 (connection) I think it varies. If you have a sub-fiber that does its own requests to the DB, you don't want to inherit the connection. But if it's an iterator fiber you do want to inherit the connection. So it depends on what "kind" of fiber, how it is used. Actually, for an iterator fiber, you'd probably want to inherit all state, even if it wasn't explicitly specified as inheritable. So maybe something like `Fiber.new(inherit: true)` would be better for that case.
What about when transfering control from one fiber to another?
```ruby
producer = Fiber.new{loop{
puts "on behalf of #{Thread.current[:request_id] || '?'}"
puts "producing #{v=rand}"
Fiber.yield(v)
}}
Thread.current[:request_id] = SecureRandom.hex(16)
producer.resume #=> random value
```
In the code above we could argue that the producer should "inherit" the request_id via resume.
----------------------------------------
Feature #19078: Introduce `Fiber#storage` for inheritable fiber-scoped variables.
https://bugs.ruby-lang.org/issues/19078#change-100357
* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
* Assignee: ioquatix (Samuel Williams)
----------------------------------------
Pull Request: https://github.com/ruby/ruby/pull/6612
This is an evolution of the previous ideas:
- https://bugs.ruby-lang.org/issues/19058
- https://bugs.ruby-lang.org/issues/19062
This PR introduces fiber scoped variables, and is a solution for problems like <https://github.com/ioquatix/ioquatix/discussions/17>.
The main interface is:
```ruby
Fiber[key] = value
Fiber[key] # => value
```
The variables are scoped (local to) a fiber and inherited into child fibers and threads.
```ruby
Fiber[:request_id] = SecureRandom.hex(16)
Fiber.new do
p Fiber[:request_id] # prints the above request id
end
```
The fiber scoped variables are stored and can be accessed:
```ruby
Fiber.current.storage # => returns a Hash (copy) of the internal storage.
Fiber.current.storage= # => assigns a Hash (copy) to the internal storage.
```
Fiber itself has one new keyword argument:
```
Fiber.new(..., storage: hash, false, undef, nil)
```
This can control how the fiber variables are setup in a child context.
To minimise the performance overhead of some of the implementation choices, we are also simultaneously implementing <https://bugs.ruby-lang.org/issues/19077>.
## Examples
### Request loop
```ruby
Thread.new do
while request = queue.pop
Fiber.new(storage: {id: SecureRandom.hex(16)}) do
handle_request.call(request)
end
end
end
```
OR
```ruby
Thread.new do
while request = queue.pop
Fiber.current.storage = {id: SecureRandom.hex(16)}
handle_request.call(request)
end
end
```
--
https://bugs.ruby-lang.org/
Issue #19147 has been updated by mtasaka (Mamoru Tasaka).
Yes, I was about to report this, however Vít was ahead of me 👍
At least 3.2.0preview3 ( commit:git|28611be6ee84ba8eb19e667a70ae129833b98b8b ) was already failing, commit:git|6bf458eefd seemed to be okay, I have not tried bisect.
For commit:git|a1d70f5b12 (still failing): for the failing test
vo.x (Vit Ondruch) wrote:
> 2) Error:
> TestDir#test_home:
> RuntimeError: can't set length of shared string
> /builddir/build/BUILD/ruby-3.2.0-66e5200ba4/test/ruby/test_dir.rb:537:in `expand_path'
> /builddir/build/BUILD/ruby-3.2.0-66e5200ba4/test/ruby/test_dir.rb:537:in `block in test_home'
> ~~~
Backtrace is:
```
[mockbuild@3caf95c4eff64519bbdc3426938b6da2 redhat-linux-build]$ gdb --args ./miniruby -I/builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/lib -I. -I.ext/common /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/tool/runruby.rb --extout=.ext -- --disable-gems /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/test/ruby/test_dir.rb
GNU gdb (GDB) Fedora Linux 12.1-9.fc38
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./miniruby...
(gdb) break vfork
Breakpoint 1 at 0x1e860
(gdb) r
Starting program: /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/redhat-linux-build/miniruby -I/builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/lib -I. -I.ext/common /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/tool/runruby.rb --extout=.ext -- --disable-gems /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/test/ruby/test_dir.rb
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
process 4106 is executing new program: /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/redhat-linux-build/ruby
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.36.9000-13.fc38.i686 gmp-6.2.1-3.fc37.i686 libgcc-12.2.1-4.fc38.i686 libxcrypt-4.4.33-3.fc38.i686 zlib-1.2.12-5.fc38.i686
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
Run options:
--seed=42337
# Running tests:
Breakpoint 1, 0xf78e5e60 in vfork () from /lib/libc.so.6
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.36.9000-13.fc38.i686 gmp-6.2.1-3.fc37.i686 libgcc-12.2.1-4.fc38.i686 libxcrypt-4.4.33-3.fc38.i686 zlib-1.2.12-5.fc38.i686
(gdb) break string.c:3021
Breakpoint 2 at 0xf7bc1379: file /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/string.c, line 3021.
(gdb) c
Continuing.
[Detaching after vfork from child process 4109]
[18/36] TestDir#test_glob_too_may_open_files
Breakpoint 1, 0xf78e5e60 in vfork () from /lib/libc.so.6
(gdb) c
Continuing.
[Detaching after vfork from child process 4110]
[New Thread 0xf4b44b40 (LWP 4111)]
[24/36] TestDir#test_glob_gc_for_fd
Thread 1 "ruby" hit Breakpoint 1, 0xf78e5e60 in vfork () from /lib/libc.so.6
(gdb)
Continuing.
[Detaching after vfork from child process 4112]
[Thread 0xf4b44b40 (LWP 4111) exited]
[New Thread 0xf4b44b40 (LWP 4113)]
[33/36] TestDir#test_home
Thread 1 "ruby" hit Breakpoint 2, rb_str_set_len (str=4105702440, len=9) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/string.c:3021
3021 rb_raise(rb_eRuntimeError, "can't set length of shared string");
(gdb) bt
#0 rb_str_set_len (str=4105702440, len=9) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/string.c:3021
#1 0xf7aa9fb1 in rb_file_expand_path_internal (fname=<optimized out>, fname@entry=4105702460, dname=dname@entry=2, abs_mode=abs_mode@entry=0, long_name=1, result=4105702440)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/file.c:3895
#2 0xf7aaa8f6 in rb_file_expand_path (fname=4105702460, dname=2) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/file.c:4151
#3 0xf7aaa94b in rb_file_s_expand_path (argc=1, argv=0xf776a290) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/file.c:4164
#4 0xf7aaa980 in s_expand_path (c=1, v=0xf776a290, _=4151513920) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/file.c:4198
#5 0xf7c1b86a in vm_call_cfunc_with_frame (ec=0x5655c0bc, reg_cfp=0xf77e9cb0, calling=0xffffbba0) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_insnhelper.c:3233
#6 0xf7c1f7b9 in vm_sendish (ec=0x5655c0bc, reg_cfp=0xf77e9cb0, cd=0x56626b50, block_handler=0, method_explorer=mexp_search_method) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_callinfo.h:367
#7 0xf7c21a54 in vm_exec_core (ec=0x6001, initial=9437189) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/redhat-linux-build/insns.def:820
#8 0xf7c38154 in rb_vm_exec (ec=0x5655c0bc, jit_enable_p=true) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:2370
#9 0xf7c2b854 in invoke_block (captured=0xf77e9d9c, opt_pc=<optimized out>, type=572653569, cref=0x0, self=4105695760, iseq=0xf775e980, ec=0x5655c0bc)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1389
#10 invoke_iseq_block_from_c (me=0x0, is_lambda=<optimized out>, cref=0x0, passed_block_handler=0, kw_splat=0, argv=0xffffbee0, argc=1, self=4105695760, captured=<optimized out>, ec=0x5655c0bc)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1445
#11 invoke_block_from_c_bh (force_blockarg=<optimized out>, is_lambda=<optimized out>, cref=<optimized out>, passed_block_handler=<optimized out>, kw_splat=<optimized out>, argv=<optimized out>,
argc=<optimized out>, block_handler=<optimized out>, ec=<optimized out>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1463
#12 vm_yield_with_cref (is_lambda=0, cref=0x0, kw_splat=0, argv=0xffffbee0, argc=1, ec=0x5655c0bc) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1500
#13 vm_yield (kw_splat=0, argv=0xffffbee0, argc=1, ec=0x5655c0bc) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1508
#14 rb_yield_0 (argv=0xffffbee0, argc=1) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_eval.c:1348
#15 rb_yield (val=<optimized out>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_eval.c:1364
#16 0xf7a3017c in rb_ary_collect (ary=4105689900) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/array.c:3830
#17 0xf7c1b86a in vm_call_cfunc_with_frame (ec=0x5655c0bc, reg_cfp=0xf77e9d90, calling=0xffffbff0) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_insnhelper.c:3233
#18 0xf7c1f7b9 in vm_sendish (ec=0x5655c0bc, reg_cfp=0xf77e9d90, cd=0x566a0f08, block_handler=4152270237, method_explorer=mexp_search_method) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_callinfo.h:367
#19 0xf7c223e3 in vm_exec_core (ec=0x6001, initial=9437189) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/redhat-linux-build/insns.def:801
#20 0xf7c38154 in rb_vm_exec (ec=0x5655c0bc, jit_enable_p=true) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:2370
#21 0xf7c2b854 in invoke_block (captured=0xf77e9e1c, opt_pc=<optimized out>, type=572653569, cref=0x0, self=4105695760, iseq=0xf4bd082c, ec=0x5655c0bc)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1389
#22 invoke_iseq_block_from_c (me=0x0, is_lambda=<optimized out>, cref=0x0, passed_block_handler=0, kw_splat=0, argv=0xffffc330, argc=1, self=4105695760, captured=<optimized out>, ec=0x5655c0bc)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1445
#23 invoke_block_from_c_bh (force_blockarg=<optimized out>, is_lambda=<optimized out>, cref=<optimized out>, passed_block_handler=<optimized out>, kw_splat=<optimized out>, argv=<optimized out>,
argc=<optimized out>, block_handler=<optimized out>, ec=<optimized out>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1463
#24 vm_yield_with_cref (is_lambda=0, cref=0x0, kw_splat=0, argv=0xffffc330, argc=1, ec=0x5655c0bc) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1500
#25 vm_yield (kw_splat=0, argv=0xffffc330, argc=1, ec=0x5655c0bc) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1508
#26 rb_yield_0 (argv=0xffffc330, argc=1) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_eval.c:1348
#27 rb_yield (val=<optimized out>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_eval.c:1364
#28 0xf7a2ff2a in rb_ary_each (ary=<optimized out>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/array.c:2733
#29 rb_ary_each (ary=4106062620) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/array.c:2727
#30 0xf7c1b86a in vm_call_cfunc_with_frame (ec=0x5655c0bc, reg_cfp=0xf77e9e10, calling=0xffffc430) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_insnhelper.c:3233
#31 0xf7c1f7b9 in vm_sendish (ec=0x5655c0bc, reg_cfp=0xf77e9e10, cd=0x566449d0, block_handler=4152270365, method_explorer=mexp_search_method) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_callinfo.h:367
#32 0xf7c223e3 in vm_exec_core (ec=0x6001, initial=9437189) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/redhat-linux-build/insns.def:801
#33 0xf7c38154 in rb_vm_exec (ec=0x5655c0bc, jit_enable_p=true) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:2370
#34 0xf7c2b854 in invoke_block (captured=0xf77e9efc, opt_pc=<optimized out>, type=572653569, cref=0x0, self=4105695760, iseq=0xf775dbc0, ec=0x5655c0bc)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1389
#35 invoke_iseq_block_from_c (me=0x0, is_lambda=<optimized out>, cref=0x0, passed_block_handler=0, kw_splat=0, argv=0xffffc770, argc=1, self=4105695760, captured=<optimized out>, ec=0x5655c0bc)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1445
--Type <RET> for more, q to quit, c to continue without paging--
#36 invoke_block_from_c_bh (force_blockarg=<optimized out>, is_lambda=<optimized out>, cref=<optimized out>, passed_block_handler=<optimized out>, kw_splat=<optimized out>, argv=<optimized out>,
argc=<optimized out>, block_handler=<optimized out>, ec=<optimized out>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1463
#37 vm_yield_with_cref (is_lambda=0, cref=0x0, kw_splat=0, argv=0xffffc770, argc=1, ec=0x5655c0bc) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1500
#38 vm_yield (kw_splat=0, argv=0xffffc770, argc=1, ec=0x5655c0bc) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1508
#39 rb_yield_0 (argv=0xffffc770, argc=1) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_eval.c:1348
#40 rb_yield (val=<optimized out>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_eval.c:1364
#41 0xf7a2ff2a in rb_ary_each (ary=<optimized out>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/array.c:2733
#42 rb_ary_each (ary=4106063400) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/array.c:2727
#43 0xf7c1b86a in vm_call_cfunc_with_frame (ec=0x5655c0bc, reg_cfp=0xf77e9ef0, calling=0xffffc870) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_insnhelper.c:3233
#44 0xf7c1f7b9 in vm_sendish (ec=0x5655c0bc, reg_cfp=0xf77e9ef0, cd=0x566a44a0, block_handler=4152270589, method_explorer=mexp_search_method) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm_callinfo.h:367
#45 0xf7c223e3 in vm_exec_core (ec=0x6001, initial=9437189) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/redhat-linux-build/insns.def:801
#46 0xf7c38154 in rb_vm_exec (ec=0x5655c0bc, jit_enable_p=true) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:2370
#47 0xf7c39044 in invoke_block (captured=0x567345a0, opt_pc=<optimized out>, type=<optimized out>, cref=0x0, self=<optimized out>, iseq=<optimized out>, ec=0x5655c0bc)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1389
#48 invoke_iseq_block_from_c (me=0x0, is_lambda=<optimized out>, cref=0x0, passed_block_handler=0, kw_splat=0, argv=<optimized out>, argc=0, self=4105727080, captured=0x567345a0, ec=0x5655c0bc)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1445
#49 invoke_block_from_c_proc (me=0x0, is_lambda=<optimized out>, passed_block_handler=0, kw_splat=0, argv=<optimized out>, argc=0, self=4105727080, proc=<optimized out>, ec=0x5655c0bc)
at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1543
#50 vm_invoke_proc (ec=0x5655c0bc, proc=<optimized out>, self=4105727080, argc=0, argv=0xf4b7f4c0, kw_splat=0, passed_block_handler=0) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/vm.c:1573
#51 0xf7b60938 in rb_proc_call_kw (self=<optimized out>, args=<optimized out>, kw_splat=0) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/proc.c:995
#52 0xf7b609d2 in rb_proc_call (self=4105722640, args=4105696440) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/proc.c:1005
#53 0xf7a9c805 in rb_call_end_proc (data=4105722640) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/eval_jump.c:13
#54 0xf7a9c5c6 in exec_end_procs_chain (errp=0x5655c0f8, procs=0xf7dfea04 <end_procs.lto_priv>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/eval_jump.c:105
#55 rb_ec_exec_end_proc (ec=ec@entry=0x5655c0bc) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/eval_jump.c:120
#56 0xf7a9d655 in rb_ec_teardown (ec=0x5655c0bc) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/eval.c:159
#57 0xf7a9d8f1 in rb_ec_cleanup (ec=ec@entry=0x5655c0bc, ex=RUBY_TAG_NONE) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/eval.c:212
#58 0xf7a9e096 in ruby_run_node (n=0xf775a448) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/eval.c:330
#59 0x565561da in rb_main (argv=0xffffd064, argc=3) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/main.c:38
#60 main (argc=<optimized out>, argv=<optimized out>) at /builddir/build/BUILD/ruby-3.2.0-a1d70f5b12/main.c:57
```
----------------------------------------
Bug #19147: `TestFileExhaustive#test_expand_path_for_existent_username` and `TestDir#test_home` fails on i686
https://bugs.ruby-lang.org/issues/19147#change-100355
* Author: vo.x (Vit Ondruch)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.2.0dev (2022-11-24 master 66e5200ba4) [i386-linux]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Testing with commit:git|66e5200ba4 on Fedora Rawhide, I observe following error just on i686 (other platforms are passing just fine):
~~~
1) Error:
TestFileExhaustive#test_expand_path_for_existent_username:
RuntimeError: can't set length of shared string
/builddir/build/BUILD/ruby-3.2.0-66e5200ba4/test/ruby/test_file_exhaustive.rb:1122:in `expand_path'
/builddir/build/BUILD/ruby-3.2.0-66e5200ba4/test/ruby/test_file_exhaustive.rb:1122:in `test_expand_path_for_existent_username'
2) Error:
TestDir#test_home:
RuntimeError: can't set length of shared string
/builddir/build/BUILD/ruby-3.2.0-66e5200ba4/test/ruby/test_dir.rb:537:in `expand_path'
/builddir/build/BUILD/ruby-3.2.0-66e5200ba4/test/ruby/test_dir.rb:537:in `block in test_home'
~~~
Previously testing with commit:git|4b1504ae0a, the tests were passing just fine.
--
https://bugs.ruby-lang.org/
Issue #18779 has been updated by vo.x (Vit Ondruch).
If it helps, this [1] is the patch we are carrying around in Fedora for Ruby 3.1. I would appreciate if is backported, because it influences files which are pregenerated and part of the release tarball [2].
[1]: https://src.fedoraproject.org/rpms/ruby/blob/9819174c8dd5a04f7cc47d50d586cc…
[2]: https://src.fedoraproject.org/rpms/ruby/blob/9819174c8dd5a04f7cc47d50d586cc…
----------------------------------------
Bug #18779: `GC.compact` and other compaction related methods should be defined as rb_f_notimplement on non supported platforms.
https://bugs.ruby-lang.org/issues/18779#change-100354
* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
* Backport: 2.7: WONTFIX, 3.0: REQUIRED, 3.1: REQUIRED
----------------------------------------
I received several bug report on native gems using `GC.verify_compaction_references` in their test suite.
Examples:
- https://github.com/msgpack/msgpack-ruby/pull/275/files
- https://github.com/Shopify/bootsnap/pull/414/files
I think that when `!GC_COMPACTION_SUPPORTED`, rather than raise `NotImplementedError`, we should instead define these methods as `rb_f_notimplement` like `Process.fork` on Windows.
This way `GC.respond_to?(:compact)` would be a proper way to test for compaction support.
Unfortunately, these methods are defined through `.rb` files with `Primitive`, and I don't know wether it's possible to check `GC_COMPACTION_SUPPORTED` from there, nor if it's possible to define a `rb_f_notimplement` method.
cc @tenderlovemaking
--
https://bugs.ruby-lang.org/
Issue #18976 has been updated by hsbt (Hiroshi SHIBATA).
I'm considering to migrate the following plan:
* I'll build the simple txt archives like `https://blade.ruby-lang.org/ruby-core/xxxxxx`.
* I restore mailing-list data to it with ruby-core, ruby-dev, ruby-list, ruby-ext and ruby-math.
* Change archive link of bugs.ruby-lang.org to them.
* I'll create the mirror program for the new mail for ruby-core and ruby-dev. other lists will use https://ml.ruby-lang.org/mailman3/hyperkitty/.
* hyperkitty UI didn't provide url with post_id. We couldn't associate this UI and bugs.ruby-lang.org simply.
----------------------------------------
Misc #18976: [ANN] blade.ruby-lang.org is down
https://bugs.ruby-lang.org/issues/18976#change-100351
* Author: hsbt (Hiroshi SHIBATA)
* Status: Assigned
* Priority: Normal
* Assignee: hsbt (Hiroshi SHIBATA)
----------------------------------------
The mail archive server named `blade.nagaokaut.ac.jp` is down now.
blade had some hardware issues. Prof. Hara tries to salvage mail data and rebuild blade. But It's difficult status.
I have a plan to migrate Ruby mail server includes mailing-list to Google workspace. I also rebuild mail archives using Google groups or others.
Sorry for the inconvenient experience.
FYI: original announce in Japanese https://github.com/ruby-no-kai/official/issues/306#issuecomment-1207819210
--
https://bugs.ruby-lang.org/
Issue #13221 has been updated by hsbt (Hiroshi SHIBATA).
Status changed from Assigned to Closed
Assignee changed from naruse (Yui NARUSE) to hsbt (Hiroshi SHIBATA)
There is no plan to add curses as the bundled gems now. I'll close this.
----------------------------------------
Feature #13221: [PATCH] gems/bundled_gems: add "curses" RubyGem
https://bugs.ruby-lang.org/issues/13221#change-100346
* Author: normalperson (Eric Wong)
* Status: Closed
* Priority: Normal
* Assignee: hsbt (Hiroshi SHIBATA)
----------------------------------------
This was part of the standard library in Ruby 2.0 and earlier;
and some users may still expect it to be in the standard
install.
---Files--------------------------------
0001-gems-bundled_gems-add-curses-RubyGem.patch (624 Bytes)
--
https://bugs.ruby-lang.org/
Issue #19000 has been updated by Dan0042 (Daniel DeLorme).
p8 (Petrik de Heus) wrote in #note-18:
> If `dup` is chosen would it make sense to always allow `dup` methods to take arguments for consistency?
It would make sense, but it would require everyone who wrote a custom `#dup` to extend their version to support this new API pattern. Not likely to happen.
On the other hand with `#with` it would be possible to implement a general version for all objects
```ruby
def with(attr={})
attr.each_with_object(self.dup) do |(k,v),obj|
obj.send("#{k}=", v)
end
end
```
(but let's keep in mind this proposal is about Data#with, not Object#with)
----------------------------------------
Feature #19000: Data: Add "Copy with changes method" [Follow-on to #16122 Data: simple immutable value object]
https://bugs.ruby-lang.org/issues/19000#change-100341
* Author: RubyBugs (A Nonymous)
* Status: Open
* Priority: Normal
----------------------------------------
*As requested: extracted a follow-up to #16122 Data: simple immutable value object from [this comment](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/109815)*
# Proposal: Add a "Copy with changes" method to Data
Assume the proposed `Data.define` exists.
Seeing examples from the [[Values gem]](https://github.com/ms-ati/Values):
```ruby
# A new class
Point = Data.def(:x, :y)
# An immutable instance
Origin = Point.with(x: 0, y: 0)
# Q: How do we make copies that change 1 or more values?
right = Origin.with(x: 1.0)
up = Origin.with(y: 1.0)
up_and_right = right.with(y: up.y)
# In loops
movements = [
{ x: +0.5 },
{ x: +0.5 },
{ y: -1.0 },
{ x: +0.5 },
]
# position = Point(x: 1.5, y: -1.0)
position = movements.inject(Origin) { |p, move| p.with(**move) }
```
## Proposed detail: Call this method: `#with`
```ruby
Money = Data.define(:amount, :currency)
account = Money.new(amount: 100, currency: 'USD')
transactions = [+10, -5, +15]
account = transactions.inject(account) { |a, t| a.with(amount: a.amount + t) }
#=> Money(amount: 120, currency: "USD")
```
## Why add this "Copy with changes" method to the Data simple immutable value class?
Called on an instance, it returns a new instance with only the provided parameters changed.
This API affordance is now **widely adopted across many languages** for its usefulness. Why is it so useful? Because copying immutable value object instances, with 1 or more discrete changes to specific fields, is the proper and ubiquitous pattern that takes the place of mutation when working with immutable value objects.
**Other languages**
C# Records: “immutable record structs — Non-destructive mutation” — is called `with { ... }`
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-t…
Scala Case Classes — is called `#copy`
https://docs.scala-lang.org/tour/case-classes.html
Java 14+ Records — Brian Goetz at Oracle is working on adding a with copy constructor inspired by C# above as we speak, likely to be called `#with`
https://mail.openjdk.org/pipermail/amber-spec-experts/2022-June/003461.html
Rust “Struct Update Syntax” via `..` syntax in constructor
https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-insta…
## Alternatives
Without a copy-with-changes method, one must construct entirely new instances using the constructor. This can either be (a) fully spelled out as boilerplate code, or (b) use a symmetrical `#to_h` to feed the keyword-args constructor.
**(a) Boilerplate using constructor**
```ruby
Point = Data.define(:x, :y, :z)
Origin = Point.new(x: 0.0, y: 0.0, z: 0.0)
change = { z: -1.5 }
# Have to use full constructor -- does this even work?
point = Point.new(x: Origin.x, y: Origin.y, **change)
```
**(b) Using a separately proposed `#to_h` method and constructor symmetry**
```ruby
Point = Data.define(:x, :y, :z)
Origin = Point.new(x: 0.0, y: 0.0, z: 0.0)
change = { z: -1.5 }
# Have to use full constructor -- does this even work?
point = Point.new(**(Origin.to_h.merge(change)))
```
Notice that the above are not ergonomic -- leading so many of our peer language communities to adopt the `#with` method to copy an instance with discrete changes.
--
https://bugs.ruby-lang.org/
Issue #19000 has been updated by Eregon (Benoit Daloze).
p8 (Petrik de Heus) wrote in #note-18:
> If `dup` is chosen would it make sense to always allow `dup` methods to take arguments for consistency?
I'm rather against that, it makes the standard `dup` so much more complicated, and it would most likely be pretty slow in CRuby.
If it's only for Data it's a much smaller concern.
----------------------------------------
Feature #19000: Data: Add "Copy with changes method" [Follow-on to #16122 Data: simple immutable value object]
https://bugs.ruby-lang.org/issues/19000#change-100340
* Author: RubyBugs (A Nonymous)
* Status: Open
* Priority: Normal
----------------------------------------
*As requested: extracted a follow-up to #16122 Data: simple immutable value object from [this comment](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/109815)*
# Proposal: Add a "Copy with changes" method to Data
Assume the proposed `Data.define` exists.
Seeing examples from the [[Values gem]](https://github.com/ms-ati/Values):
```ruby
# A new class
Point = Data.def(:x, :y)
# An immutable instance
Origin = Point.with(x: 0, y: 0)
# Q: How do we make copies that change 1 or more values?
right = Origin.with(x: 1.0)
up = Origin.with(y: 1.0)
up_and_right = right.with(y: up.y)
# In loops
movements = [
{ x: +0.5 },
{ x: +0.5 },
{ y: -1.0 },
{ x: +0.5 },
]
# position = Point(x: 1.5, y: -1.0)
position = movements.inject(Origin) { |p, move| p.with(**move) }
```
## Proposed detail: Call this method: `#with`
```ruby
Money = Data.define(:amount, :currency)
account = Money.new(amount: 100, currency: 'USD')
transactions = [+10, -5, +15]
account = transactions.inject(account) { |a, t| a.with(amount: a.amount + t) }
#=> Money(amount: 120, currency: "USD")
```
## Why add this "Copy with changes" method to the Data simple immutable value class?
Called on an instance, it returns a new instance with only the provided parameters changed.
This API affordance is now **widely adopted across many languages** for its usefulness. Why is it so useful? Because copying immutable value object instances, with 1 or more discrete changes to specific fields, is the proper and ubiquitous pattern that takes the place of mutation when working with immutable value objects.
**Other languages**
C# Records: “immutable record structs — Non-destructive mutation” — is called `with { ... }`
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-t…
Scala Case Classes — is called `#copy`
https://docs.scala-lang.org/tour/case-classes.html
Java 14+ Records — Brian Goetz at Oracle is working on adding a with copy constructor inspired by C# above as we speak, likely to be called `#with`
https://mail.openjdk.org/pipermail/amber-spec-experts/2022-June/003461.html
Rust “Struct Update Syntax” via `..` syntax in constructor
https://doc.rust-lang.org/book/ch05-01-defining-structs.html#creating-insta…
## Alternatives
Without a copy-with-changes method, one must construct entirely new instances using the constructor. This can either be (a) fully spelled out as boilerplate code, or (b) use a symmetrical `#to_h` to feed the keyword-args constructor.
**(a) Boilerplate using constructor**
```ruby
Point = Data.define(:x, :y, :z)
Origin = Point.new(x: 0.0, y: 0.0, z: 0.0)
change = { z: -1.5 }
# Have to use full constructor -- does this even work?
point = Point.new(x: Origin.x, y: Origin.y, **change)
```
**(b) Using a separately proposed `#to_h` method and constructor symmetry**
```ruby
Point = Data.define(:x, :y, :z)
Origin = Point.new(x: 0.0, y: 0.0, z: 0.0)
change = { z: -1.5 }
# Have to use full constructor -- does this even work?
point = Point.new(**(Origin.to_h.merge(change)))
```
Notice that the above are not ergonomic -- leading so many of our peer language communities to adopt the `#with` method to copy an instance with discrete changes.
--
https://bugs.ruby-lang.org/
Issue #19090 has been updated by Eregon (Benoit Daloze).
Thank you for the explanation, that's very good arguments and they address my concerns.
----------------------------------------
Feature #19090: Do not duplicate an unescaped string in CGI.escapeHTML
https://bugs.ruby-lang.org/issues/19090#change-100339
* Author: k0kubun (Takashi Kokubun)
* Status: Closed
* Priority: Normal
----------------------------------------
## Proposal
Stop guaranteeing that `GGI.escapeHTML` returns a new string even if there's nothing to be escaped.
More specifically, stop calling this `rb_str_dup` https://github.com/ruby/cgi/blob/v0.3.3/ext/cgi/escape/escape.c#L72 for the case that nothing needs to be escaped.
## Background
My original implementation https://github.com/ruby/ruby/pull/1164 was not calling it. The reason why `rb_str_dup` was added was that [Bug #11858] claimed returning the argument object for non-escaped cases is a backward incompatibility because the original `gsub`-based implementation always returns a new object. As a result, even while many people use `CGI.escapeHTML` as an optimized implementation for escaping HTML today, it ended up having a compromised performance.
## Motivation
The motivation is to improve performance. By just doing so, escaping a pre-allocated `"string"` becomes 1.34x faster on my machine https://gist.github.com/k0kubun/f66d6fe1e6ba821e4263257e504ba28f.
The most major use case of `CGP.escapeHTML` is to safely embed a user input. When the result is just embedded in another string, the allocated new object will be just wasted. It's pretty common that an embedded string fragment doesn't contain any of `'"&<>` characters. So we should stop wasting that to optimize that case.
[Bug #11858] wasn't really a use case but just "I think this is backward incompatibility" based on frozen Hello World. Unlike user input, you usually don't need to escape your own string literal. It feels like the ticket addressed a problem that doesn't exist in actual applications. It should have cited existing code that could be broken by that, and I can't find such code with `gem-codesearch` today.
The only reason to maintain the current behavior would be to allow using a return value of `CGI.escapeHTML` as a buffer for creating another longer string starting with the escaped value, but using `CGI.escapeHTML` to initialize a string buffer feels like an abuse. Relying on the behavior never makes sense as an "optimization" either because it makes all other cases (the result is not used as a string buffer) suboptimal.
## Why not an optional flag like `CGI.escapeHTML(str, dup: false)`?
Two reasons:
* The non-dup behavior should be used 99.999..9% of the time. We shouldn't make code using `CGI.escapeHTML` less readable just for maintaining a use case that doesn't exist.
* Passing keyword arguments to a C extension is unfortunately slow, and it defeats the optimization purpose. In core classes, we could use `Primitive` to address that, but this is a default gem and we can't use that.
* We could workaround that if we choose `CGI.escapeHTML(str, false)`, but again it'd spoil the readability for maintaining an invalid use case.
## Why not a new method?
It's a good idea actually, but with `escapeHTML`, `escape_html`, and `h` aliased to it already, I can't think of a good name for it. And again, not calling it `escapeHTML` or `escape_html` would spoil the readability for no valid reason.
--
https://bugs.ruby-lang.org/