[#113107] [Ruby master Bug#19576] Backport request: Gemfile.lock resolving is broken with bundler shipped with Ruby 3.1.4 — "jprokop (Jarek Prokop) via ruby-core" <ruby-core@...>

Issue #19576 has been reported by jprokop (Jarek Prokop).

8 messages 2023/04/04

[#113112] [Ruby master Bug#19578] abort() shows stack trace when run within rescue clause — "Dan0042 (Daniel DeLorme) via ruby-core" <ruby-core@...>

Issue #19578 has been reported by Dan0042 (Daniel DeLorme).

8 messages 2023/04/04

[#113180] [Ruby master Feature#19588] Allow Comparable#clamp(min, max) to accept nil as a specification — "kyanagi (Kouhei Yanagita) via ruby-core" <ruby-core@...>

Issue #19588 has been reported by kyanagi (Kouhei Yanagita).

7 messages 2023/04/11

[#113209] [Ruby master Bug#19596] Decreased performance after upgrading from ruby 2.7.2 to ruby 3.2.2 — silva96 via ruby-core <ruby-core@...>

Issue #19596 has been reported by silva96 (Benjam=EDn Silva).

7 messages 2023/04/13

[#113238] [Ruby master Misc#19599] DevMeeting-2023-05-10 — "mame (Yusuke Endoh) via ruby-core" <ruby-core@...>

Issue #19599 has been reported by mame (Yusuke Endoh).

14 messages 2023/04/14

[#113285] [Ruby master Bug#19607] Introduce `Hash#symbolize_keys`. — "ioquatix (Samuel Williams) via ruby-core" <ruby-core@...>

Issue #19607 has been reported by ioquatix (Samuel Williams).

8 messages 2023/04/18

[#113303] [Ruby master Feature#19610] GC.delay_promotion — "peterzhu2118 (Peter Zhu) via ruby-core" <ruby-core@...>

Issue #19610 has been reported by peterzhu2118 (Peter Zhu).

9 messages 2023/04/20

[#113313] [Ruby master Bug#19613] Add version information to all function documentation — "fulldecent (William Entriken) via ruby-core" <ruby-core@...>

Issue #19613 has been reported by fulldecent (William Entriken).

7 messages 2023/04/23

[#113342] [Ruby master Feature#19617] Add Method#binding and UnboundMethod#binding, similar to Proc#binding — "nevans (Nicholas Evans) via ruby-core" <ruby-core@...>

Issue #19617 has been reported by nevans (Nicholas Evans).

9 messages 2023/04/25

[#113381] [Ruby master Bug#19624] Backticks - IO object leakage — pineman via ruby-core <ruby-core@...>

Issue #19624 has been reported by pineman (Jo=E3o Pinheiro).

10 messages 2023/04/30

[ruby-core:113131] [Ruby master Feature#18368] Range#step semantics for non-Numeric ranges

From: "zverok (Victor Shepelev) via ruby-core" <ruby-core@...>
Date: 2023-04-05 14:16:57 UTC
List: ruby-core #113131
Issue #18368 has been updated by zverok (Victor Shepelev).


@Dan0042 I value backwards compatibility a lot (I mentioned it in original ticket).

I though believe that in _this_ particular case the old behaviour for non-numeric ranges is so weird that
1. Very small amount of code, if any, would be broken
2. The error would be very clear
3. Preserving both behaviours just for strings would be very hard to explain in hindsight and will affect language's quality and learnability. 

----------------------------------------
Feature #18368: Range#step semantics for non-Numeric ranges
https://bugs.ruby-lang.org/issues/18368#change-102665

* 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/
 ______________________________________________
 ruby-core mailing list -- [email protected]
 To unsubscribe send an email to [email protected]
 ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/

In This Thread