Issue #19144 has been updated by kjtsanaktsidis (KJ Tsanaktsidis).
@akr could you take a look at my PR when you get a chance? I think I addressed your feedback, please let me know if I have misunderstood!
----------------------------------------
Bug #19144: Ruby should set AI_V4MAPPED | AI_ADDRCONFIG getaddrinfo flags by default
https://bugs.ruby-lang.org/issues/19144#change-102145
* Author: kjtsanaktsidis (KJ Tsanaktsidis)
* Status: Feedback
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
Currently, DNS lookups made with `getaddrinfo` from Ruby (i.e. not from the `Resolv` module) cause both A and AAAA DNS requests to be made, even on systems that don’t actually have an IPv6 address that could possibly make the AAAA response useful. I wouldn’t _really_ care about this, normally, but glibc has a bug (https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1961697) which can cause a 5-second delay in DNS lookups when both A and AAAA records are queried in parallel. This bug is fixed in glibc upstream but still present in some LTS linux distros (Ubuntu 18.04 and 20.04 at least), so I think it’s worthwhile to try and work around it in circumstances where the AAAA request is pointless anyway.
The dual A/AAAA lookup happens because whenever Ruby calls getaddrinfo to perform DNS lookups, it always sets `hints`, and sets `hints->ai_flags` to zero by default unless flags are specified by the caller (e.g. `AI_PASSIVE` is set when binding a TCP server socket in `TCPServer.new`).
This matches the default value of `ai_flags` specified by POSIX, which is zero. However, glibc behaves differently. When glibc’s `getaddrinfo` function is called with `NULL` for the `hints` parameter, it defaults the `ai_flags` value to `(AI_V4MAPPED | AI_ADDRCONFIG)`. The manpage (from the Linux man-pages project - https://man7.org/linux/man-pages/man3/getaddrinfo.3.html) claims “this is an improvement on the standard” (although I couldn’t find this mentioned in the glibc manual itself).
Of course, we’re not _actually_ ever calling `getaddrinfo` with NULL `hints`; so, we never actually use these flags on glibc systems (unless they’re explicitly specified by the caller).
My proposal is that we should change Ruby to set these two flags by default, when they’re available, in the following circumstances:
* In all calls made internally to `rsock_getaddrinfo` as a result of socket functions like `TCPSocket.new`, `UDPSocket.new`, etc.
* EXCEPT when `AI_PASSIVE` is also set (i.e. when we’re trying to get an address to bind for listener socket - see below)
* In calls made to `rsock_getaddrinfo` as a direct result of calling `Addrinfo.getaddrinfo` from Ruby with nil flags
* EXCEPT calls to `Addrinfo.getaddrinfo` where explicit flags are provided
Both of these seem like something you would almost always want to be doing in any outgoing connection scenario:
* `AI_V4MAPPED` ensures that, if AF_INET6 is explicitly specified as the desired protocol, and there is no AAAA record in DNS, that any A record that _is_ present gets converted to an IPv4-mapped IPv6 address so it can be used e.g. with NAT64.
* `AI_ADDRCONFIG` ensures that, if a machine has no IPv6 address, it doesn’t bother making an AAAA lookup that will return IPv6 addresses that can’t actually be used for anything (and vice versa for IPv4).
The reason why we wouldn’t want to set `AI_ADDRCONFIG` in circumstances where Ruby currently sets `AI_PASSIVE` is that loopback addresses are not considered in deciding if a system has an IPv4/IPv6 address. Conceivably, you might want to bind to a `::1` loopback address, and allow other processes on the same machine to connect to that.
Does changing this default sound reasonable? If so I can prepare a patch. Another option I considered is doing this _only_ when Ruby is built against glibc (so that other system behaviour is most closely matched).
--
https://bugs.ruby-lang.org/
Issue #18368 has been updated by zverok (Victor Shepelev).
The PR is here: https://github.com/ruby/ruby/pull/7444
Clarification of semantics led to a few minor changes of behavior for numeric steps, too:
* Consistent support for negative step:
```ruby
p (1..-10).step(-3).to_a
#=> [1, -2, -5, -8] -- ArithmeticSequence backward iteration, on Ruby 3.2 and master
(1..-10).step(-3) { p _1 }
# Ruby 3.2: step can't be negative (ArgumentError) -- inconsistent with ArithmeticSequence behavior
# master: prints 1, -2, -5, -8, consistent with ArithmeticSequence
```
* Less greedy float conversion:
```ruby
require 'active_support/all'
p (1.0..).step(2.minutes).take(3)
# 3.2: [1.0, 121.0, 241.0] -- forces any passed value to be float if it has #to_f
# master: [1.0, 2 minutes and 1.0 second, 4 minutes and 1.0 second] -- properly uses step#coerce to find a suitable type
```
* Drop support for generic `#to_int`. Before, it was considered that integer is (almost) always the intended step value, so the step tried to be converted to `#to_int` if it wasn't numeric:
```ruby
o = Object.new
def o.to_int
2
end
p (1..6).step(o).to_a
#=> [1, 3, 5] on Ruby 3.2
# Now, no assumptions on the step are made other than it should be `+`-able to `begin`:
p (1..6).step(o).to_a
# master: `+': Object can't be coerced into Integer
# But:
def o.coerce(other)
[other, 2]
end
p (1..6).step(o).to_a
#=> [1, 3, 5] on master
```
I am open to discussing those changes, but to the best of my understanding, neither of them should be severely breaking, and they are naturally following the change of the semantics.
----------------------------------------
Feature #18368: Range#step semantics for non-Numeric ranges
https://bugs.ruby-lang.org/issues/18368#change-102144
* Author: zverok (Victor Shepelev)
* Status: Open
* Priority: Normal
----------------------------------------
I am sorry if the question had already been discussed, can't find the relevant topic.
"Intuitively", this looks (for me) like a meaningful statement:
```ruby
(Time.parse('2021-12-01')..Time.parse('2021-12-24')).step(1.day).to_a
# ^^^^^ or just 24*60*60
```
Unfortunately, it doesn't work with "TypeError (can't iterate from Time)".
Initially it looked like a bug for me, but after digging a bit into code/docs, I understood that `Range#step` has an odd semantics of "advance the begin N times with `#succ`, and yield the result", with N being always integer:
```ruby
('a'..'z').step(3).first(5)
# => ["a", "d", "g", "j", "m"]
```
The fact that semantic is "odd" is confirmed by the fact that for Float it is redefined to do what I "intuitively" expected:
```ruby
(1.0..7.0).step(0.3).first(5)
# => [1.0, 1.3, 1.6, 1.9, 2.2]
```
(Like with [`Range#===` some time ago](https://bugs.ruby-lang.org/issues/14575), I believe that to be a strong proof of the wrong generic semantics, if for numbers the semantics needed to be redefined completely.)
Another thing to note is that "skip N elements" seem to be rather "generically Enumerable-related" yet it isn't defined on `Enumerable` (because nobody needs this semantics, typically!)
Hence, two questions:
* Can we redefine generic `Range#step` to new semantics (of using `begin + step` iteratively)? It is hard to imagine the amount of actual usage of the old behavior (with String?.. to what end?) in the wild
* If the answer is "no", can we define a new method with new semantics, like, IDK, `Range#over(span)`?
**UPD:** More examples of useful behavior (it is NOT only about core `Time` class):
```ruby
require 'active_support/all'
(1.minute..20.minutes).step(2.minutes).to_a
#=> [1 minute, 3 minutes, 5 minutes, 7 minutes, 9 minutes, 11 minutes, 13 minutes, 15 minutes, 17 minutes, 19 minutes]
require 'tod'
(Tod::TimeOfDay.parse("8am")..Tod::TimeOfDay.parse("10am")).step(30.minutes).to_a
#=> [#<Tod::TimeOfDay 08:00:00>, #<Tod::TimeOfDay 08:30:00>, #<Tod::TimeOfDay 09:00:00>, #<Tod::TimeOfDay 09:30:00>, #<Tod::TimeOfDay 10:00:00>]
require 'matrix'
(Vector[1, 2, 3]..).step(Vector[1, 1, 1]).take(3)
#=> [Vector[1, 2, 3], Vector[2, 3, 4], Vector[3, 4, 5]]
require 'unitwise'
(Unitwise(0, 'km')..Unitwise(1, 'km')).step(Unitwise(100, 'm')).map(&:to_s)
#=> ["0 km", "1/10 km", "1/5 km", "3/10 km", "2/5 km", "0.5 km", "3/5 km", "7/10 km", "4/5 km", "9/10 km", "1 km"]
```
**UPD:** Responding to discussion points:
**Q:** Matz is concerned that the proposed simple definition will be confusing with the classes where `+` is redefined as concatenation.
**A:** I believe that simplicity of semantics and ease of explaining ("it just uses `+` underneath, whatever `+` does, will be performed") will make the confusion minimal.
**Q:** Why not introduce new API requirement (like "class of range's `begin` should implement `increment` method, and then it will be used in `step`)
**A:** require *every* gem author to change *every* of their objects' behavior. For that, they should be aware of the change, consider it important enough to care, clearly understand the necessary semantics of implementation, have a resource to release a new version... Then all users of all such gems would be required to upgrade. The feature would be DOA (dead-on-arrival).
The two alternative ways I am suggesting: change the behavior of `#step` or introduce a new method with desired behavior:
1. Easy to explain and announce
2. Require no other code changes to immediately become useful
3. With something like [backports](https://github.com/marcandre/backports) or [ruby-next](https://github.com/ruby-next/ruby-next) easy to start using even in older Ruby version, making the code more expressive even before it would be possible for some particular app/compny to upgrade to (say) 3.2
All examples of behavior from the code above are real `irb` output with monkey-patched `Range#step`, demonstrating how little change will be needed to code outside of the `Range`.
--
https://bugs.ruby-lang.org/
Issue #19429 has been reported by mame (Yusuke Endoh).
----------------------------------------
Misc #19429: DevMeeting-2023-03-09
https://bugs.ruby-lang.org/issues/19429
* Author: mame (Yusuke Endoh)
* Status: Open
* Priority: Normal
----------------------------------------
# The next dev meeting
**Date: 2023/03/09 13:00-17:00** (JST)
Log: *TBD*
- Dev meeting *IS NOT* a decision-making place. All decisions should be done at the bug tracker.
- Dev meeting is a place we can ask Matz, nobu, nurse and other developers directly.
- Matz is a very busy person. Take this opportunity to ask him. If you can not attend, other attendees can ask instead of you (if attendees can understand your issue).
- We will write a record of the discussion in the file or to each ticket in English.
- All activities are best-effort (keep in mind that most of us are volunteer developers).
- The date, time and place of the meeting are scheduled according to when/where we can reserve Matz's time.
- *DO NOT* discuss then on this ticket, please.
# Call for agenda items
If you have a ticket that you want matz and committers to discuss, please post it into this ticket in the following format:
```
* [Ticket ref] Ticket title (your name)
* Comment (A summary of the ticket, why you put this ticket here, what point should be discussed, etc.)
```
Example:
```
* [Feature #14609] `Kernel#p` without args shows the receiver (ko1)
* I feel this feature is very useful and some people say :+1: so let discuss this feature.
```
- It is recommended to add a comment by 2023/03/06. We hold a preparatory meeting to create an agenda a few days before the dev-meeting.
- The format is strict. We'll use [this script to automatically create an markdown-style agenda](https://gist.github.com/mame/b0390509ce1491b43610b9ebb665eb86). We may ignore a comment that does not follow the format.
- Your comment is mandatory. We cannot read all discussion of the ticket in a limited time. We appreciate it if you could write a short summary and update from a previous discussion.
--
https://bugs.ruby-lang.org/
Issue #18743 has been updated by marcper (Marcelo Pereira).
@sos4nt could you please assign this issue to @matz? This is a core class problem, and he is the listed maintainer for it.
I can confirm the bug still exists in ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-linux]
----------------------------------------
Bug #18743: Enumerator#next / peek re-use each others stacktraces
https://bugs.ruby-lang.org/issues/18743#change-102126
* Author: sos4nt (Stefan Schüßler)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
I encountered an odd behavior.
If I rescue the `StopIteration` exception from `peek` and call `next` afterwards: (or vice-versa)
```ruby
# enum.rb # 1
# 2
enum = [].each # 3
enum.peek rescue nil # 4
enum.next # 5
```
it will show the stacktrace from the rescued `peek` call:
```
$ ruby enum.rb
enum.rb:4:in `peek': iteration reached an end (StopIteration)
from enum.rb:4:in `<main>'
```
Whereas the error should refer to `next` on line number 5.
The same happens when calling `peek` after `next` or when having muliple `peek` / `next` calls:
```ruby
# enum.rb # 1
# 2
enum = [].each # 3
enum.peek rescue nil # 4
enum.next rescue nil # 5
enum.peek rescue nil # 6
puts "line #{__LINE__}" # 7
enum.next # 8
```
The stacktrace from the first (rescued) `peek` or `next` call will be shown which doesn't reflect the actual error location:
```
$ ruby enum.rb
line 7
enum.rb:4:in `peek': iteration reached an end (StopIteration)
from enum.rb:4:in `<main>'
```
This is very confusing when debugging code.
---Files--------------------------------
01-Recreate-stacktrace-enumerator.patch (1.29 KB)
--
https://bugs.ruby-lang.org/
Issue #19383 has been reported by stringsn88keys (Thomas Powell).
----------------------------------------
Bug #19383: Time.now.zone encoding for German display language in Windows is incorrect
https://bugs.ruby-lang.org/issues/19383
* Author: stringsn88keys (Thomas Powell)
* Status: Open
* Priority: Normal
* ruby -v: 3.1.3
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
OS:
Verified on Windows 10 and Windows Server 2022 and Ruby 2.7.7 through 3.1.3
Display language:
Verified on German, but may impact other languages in which Time.now.zone returns characters that aren't [A-Za-z].
Time zone:
CET (UTC +01:00) Amsterdam, Berlin, ...
Time.now.zone # => "Mitteleuro\xE3ische Zeit"
Time.now.zone.encoding # => #<Encoding:IBM437>
puts Time.now.zone # => "Mitteleurop∑ische Zeit" (should be "Mitteleuropäische Zeit")
Time.now.zone.encode(Encoding::UTF_8) # => "Mitteleurop∑ische Zeit"
Doing a force_encoding on all encodings in Encoding.list reveals that ISO-8859-(1..16) and Windows-125(0,2,4,7) work to coerce the ä out of the time zone string:
Time.now.zone.force_encoding(Encoding::WINDOWS_1252) # => "Mitteleuro\xE3ische Zeit"
... but ...
Time.now.zone.force_encoding(Encoding::WINDOWS_1252).encode(Encoding::UTF_8) #=> "Mitteleuropäische Zeit"
Related issue: This improper encoding/rendering caused Ohai's JSON output to be unparseable. Workaround was forcing to Windows-1252.
https://github.com/chef/ohai/pull/1781
--
https://bugs.ruby-lang.org/
Issue #19474 has been reported by eightbitraptor (Matthew Valentine-House).
----------------------------------------
Feature #19474: Reduce the number of NEWOBJ macros
https://bugs.ruby-lang.org/issues/19474
* Author: eightbitraptor (Matthew Valentine-House)
* Status: Open
* Priority: Normal
----------------------------------------
[Github PR](https://github.com/ruby/ruby/pull/7393)
Since the introduction of variable width allocation with `RVARGC` there are a lot of different `*NEWOBJ*` macros. Currently there are:
* `RB_RVARGC_NEWOBJ_OF`
* `RB_RVARGC_EC_NEWOBJ_OF`
* `RB_NEWOBJ_OF`, an alias of `RB_RVARGC_NEWOBJ_OF`
* `RB_EC_NEWOBJ_OF`, an alias of `RB_RVARGC_EC_NEWOBJ_OF`
* `NEWOBJ_OF`, an alias of `RB_RVARGC_NEWOBJ_OF`
* `RVARGC_NEWOBJ_OF`, an alias of `RB_RVARGC_NEWOBJ_OF`
This PR merges `RB_RVARGC_NEWOBJ_OF` and `RB_RVARGC_EC_NEWOBJ_OF` into a single macro that takes the `ec` as an argument (which can be `NULL`). The resulting macro has been renamed to `RVARGC_NEWOBJ_OF` as the existing `RVARGC_NEWOBJ_OF` was an alias for `RB_RVARGC_NEWOBJ_OF`.
`RB_NEWOBJ_OF`, `RB_EC_NEWOBJ_OF` have been removed, as these were just aliases for `RB_RVARGC_NEWOBJ_OF`.
`RB_NEWOBJ_OF` and `NEWOBJ_OF` have been retained as these are part of the public API exposed in `include/ruby/internal/newobj.h` so they are available to extension authors.
--
https://bugs.ruby-lang.org/
Issue #19447 has been reported by eightbitraptor (Matthew Valentine-House).
----------------------------------------
Bug #19447: Merge `internal/rgengc.h` into public `internal/gc.h` header
https://bugs.ruby-lang.org/issues/19447
* Author: eightbitraptor (Matthew Valentine-House)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
[[Github PR #7310](https://github.com/ruby/ruby/pull/7310)]
This PR merges the `rgengc.h` internal header into the public internal `gc.h` header.
`rgengc.h` was introduced as part of this commit `9e6e39c3512f7a962c44dc3729c98a0f8be90341` when `ruby.h` was split apart. It mostly contains macros for enabling the write barrier on objects,
I have merged this into `include/ruby/internal/gc.h` in order to keep the internal GC api spread across as few places as possible.
I don't believe that this will cause a problem with C extensions despite the removal of a public header file. Both `include/ruby/internal/rgengc.h` and `include/ruby/internal/gc.h` were both included from `ruby/ruby.h` and so every C extension that `#include <ruby/ruby.h>` already has access to their definitions.
I think that the only case there would be a problem is if a user had explicitly `#include <ruby/internal/rgengc.h>` which is unneccesary if they've already included `<ruby/ruby.h>`.
--
https://bugs.ruby-lang.org/
Given the following snippet:
```
def foo = "foo"
def bar = "bar"
text = "foo"
matches = text in bar
```
The result will be "true", and bar is now a local variable with value "foo".
If you instead try
```
def foo = "foo"
def bar = "bar"
text = "foo"
matches = text in ^bar
```
You get SyntaxError: "bar: no such local variable"
The only way I've found to be able to do this as a one-liner is with something like:
```
def foo = "foo"
def bar = "bar"
text = "foo"
matches = text in ^(tmp = bar)
```
Anyone else find this behaviour a bit odd?
Issue #19378 has been reported by aidog (Andi Idogawa).
----------------------------------------
Bug #19378: Windows: Use less syscalls for faster require of big gems
https://bugs.ruby-lang.org/issues/19378
* Author: aidog (Andi Idogawa)
* Status: Open
* Priority: Normal
* ruby -v: 3.2.0
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
Hello 🙂
## Problem
require is slow on windows for big gems. (example: require 'gtk3'=> 3 seconds+). This is a problem for people who want to make cross platform GUI apps with ruby.
## Possible Reason
As touched on in [#15797](https://bugs.ruby-lang.org/issues/15797) it seems like require uses realpath, which is emulated on windows. It checks every parent directory. The same syscalls run many times.
## Testfile
C:\tmp\speedtest\testrequire.rb:
``` ruby
require __dir__ + "/helloworld1.rb"
require __dir__ + "/helloworld2.rb"
```
``` shell
ruby --disable-gems C:\tmp\speedtest\testrequire.rb
```
### Syscalls per File/Directory:
1. CreateFile
2. QueryInformationVolume
3. QueryIdInformation
4. QueryAllInformationFile
5. QueryNameInformationFile
6. QueryNameInformationFile
7. QueryNormalizedNameInformationFile
8. CloseFile
### Files/Directories checked
1. C:\tmp
2. C:\tmp\speedtest
3. C:\tmp\speedtest\helloworld1.rb
4. C:\tmp
5. C:\tmp\speedtest
6. C:\tmp\speedtest\helloworld2.rb
For two required files Ruby had to do 8*6 = **48** syscalls.
The syscalls orginate from rb_w32_reparse_symlink_p / lstat
Rubygems live in subfolders with 9+ parts: "C:\Ruby32-x64\lib\ruby\gems\3.2.0\gems\glib2-4.0.8\lib\glib2\variant.rb"
Each file takes 8 * 9 = **72**+ calls. For variant.rb it is **80** calls.
The result for the syscalls don't change in such a short time, so it should be possible to cache it.
With require_relative it's twice as many calls.
## Other testcases
Same result:
``` ruby
File.realpath __dir__ + "/helloworld1.rb"
File.realpath __dir__ + "/helloworld2.rb"
```
``` ruby
File.stat __dir__ + "/helloworld1.rb"
File.stat __dir__ + "/helloworld2.rb"
```
It does not happen in $LOAD_PATH.resolve_feature_path(__dir__ + "/helloworld1.rb")
## Request
Would it be possible to cache the stat calls when using require?
I tried to implement a cache inside the ruby source code, but failed.
If not, is there now a way to combine ruby files into one?
I previously talked about require here: [YJIT: Windows support lacking.](https://bugs.ruby-lang.org/issues/19325#note-11)
## How to reproduce
Ruby versions: At least 3.0+, most likely older ones too.
Tested using Ruby Installer 3.1 and 3.2.
[Procmon Software by Sysinternals](https://learn.microsoft.com/en-us/sysinternals/downloads/proc…
--
https://bugs.ruby-lang.org/