[#122643] [Ruby Bug#21498] Windows - Ruby Overrides C Library APIs thus breaking them — "cfis (Charlie Savage) via ruby-core" <ruby-core@...>

Issue #21498 has been reported by cfis (Charlie Savage).

9 messages 2025/07/02

[#122658] [Ruby Feature#21501] Include native filenames in backtraces as sources for native methods — "ivoanjo (Ivo Anjo) via ruby-core" <ruby-core@...>

Issue #21501 has been reported by ivoanjo (Ivo Anjo).

10 messages 2025/07/05

[#122665] [Ruby Bug#21503] \p{Word} does not match on \p{Join_Control} while docs say it does — "procmarco (Marco Concetto Rudilosso) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxNTAzIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IHByb2NtYXJjbyAoTWFyY28gQ29uY2V0

8 messages 2025/07/07

[#122734] [Ruby Bug#21511] Use-after-free of the execution context after the fiber object carrying it is freed in GC — "tuonigou (tianyang sun) via ruby-core" <ruby-core@...>

Issue #21511 has been reported by tuonigou (tianyang sun).

10 messages 2025/07/14

[#122797] [Ruby Feature#21515] Add `&return` as sugar for `x=my_calculation; return x if x` — "nhorton (Noah Horton) via ruby-core" <ruby-core@...>

Issue #21515 has been reported by nhorton (Noah Horton).

13 messages 2025/07/16

[#122842] [Ruby Feature#21518] Statistical helpers to `Enumerable` — "Amitleshed (Amit Leshed) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxNTE4IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IEFtaXRsZXNoZWQgKEFtaXQgTGVzaGVk

12 messages 2025/07/23

[#122847] [Ruby Feature#21520] Feature Proposal: Enumerator::Lazy#peek — "nuzair46 (Nuzair Rasheed) via ruby-core" <ruby-core@...>

SXNzdWUgIzIxNTIwIGhhcyBiZWVuIHJlcG9ydGVkIGJ5IG51emFpcjQ2IChOdXphaXIgUmFzaGVl

12 messages 2025/07/24

[ruby-core:122878] [Ruby Bug#21139] Prism and parse.y parses `it = it` differently

From: "jeremyevans0 (Jeremy Evans) via ruby-core" <ruby-core@...>
Date: 2025-07-28 20:21:13 UTC
List: ruby-core #122878
Issue #21139 has been updated by jeremyevans0 (Jeremy Evans).


vinistock (Vinicius Stock) wrote in #note-18:
> Thanks for the context, I understand your point about consistency. So this case
> 
> ```ruby
> 42.tap { |x| x = x; p x }
> ```
> 
> Works because by the time we reach `x = x`, the block parameter already declared `x` as a local and so it doesn't end up setting it equal to `nil`. Would it make sense to automatically declare `it` as a local inside the block?
> 
> Or another question, do we agree that these two should return the same result?
> 
> ```ruby
> 42.tap { it = it; p it }
> 42.tap { |x| x = x; p x }
> ```

No. `it` is not a local variable until it is referenced, so the first example should always print `nil` (unless `it` was already a local variable in higher scope).  Everywhere else in Ruby:

```ruby
lvar = lvar
```

Will result in `lvar` being nil if was not already a local variable in scope.

To think that `42.tap { it = it; p it }` should print 42 is to believe that `it` is a local variable before it is referenced.  However, if `it` is never referenced, then `it` is never a local variable, and the block does not accept an argument:

```ruby
proc{}.arity   # => 0
proc{it}.arity # => 1
```

You could argue that `it` is a local variable from the start of the block instead of where `it` is first referenced in the block. However, that's not how local variables work in general. Every other place in Ruby where a local variable is declared (referenced in the LHS of an assignment), it is only considered declared after the reference, not before the reference:

```
def x = 1
def y
  x # => 1
  x = x
  x # => nil
end
```

If `it` should be considered a local variable from the start of the block if it is referenced anywhere in the block, then in the above example, the first reference to `x` inside `y` should be a local variable reference instead of a method call, even though the `x` local variable is not declared until afterward.

In general, you shouldn't consider `it` to be a local variable. If `it` was a local variable, this would work:

```ruby
proc{eval("it")}.call(1) # NameError
```

But it doesn't work, even if `it` is already referenced:

```ruby
proc{it; eval("it")}.call(1) # NameError
```

If at the point of reference, `it` is already a local variable, Ruby treats it as it would any local variable. If `it` is not already a local variable, then Ruby treats it as the implicit block parameter. Inside a block, for `it = it`, the RHS `it` was previously declared as a local variable by the LHS, so it is treated as a local variable instead of as the implicit block parameter.

AMomchilov (Alexander Momchilov) wrote in #note-19:
> @jeremyevans0 I see your point about how ivars take precedence over methods of the same name, but I think `it` is more like a block argument (well, a local variable) than a method, so I find this inconsistently really surprising:
> 
> ```
> ruby --parser=parse.y -e "42.tap {      it = it; p it }" # => nil
> ruby --parser=parse.y -e "42.tap { |it| it = it; p it }" # => 42
> ```
> 
> Since `it` is just a shorthand for "the first block argument," then I think people would expect that it works _as if_ you declared `|it|` yourself.

They may. However, doing so is inconsistent with how local variables are designed in Ruby. Personally, I think consistency is much more important in this case. I cannot think of a good reason to define an `it` local variable while also using `it` as the implicit block parameter. If you are only using `it` in the same block scope, no local variable is necessary. If you are setting `it` to a local variable so it is usable inside a nested block, you should pick a different variable name, as using `it` is more likely to cause confusion.

----------------------------------------
Bug #21139: Prism and parse.y parses `it = it` differently
https://bugs.ruby-lang.org/issues/21139#change-114181

* Author: tompng (tomoya ishida)
* Status: Feedback
* Assignee: prism
* ruby -v: ruby 3.5.0dev (2025-02-14T16:49:52Z master ee181d1bb7) +PRISM [x86_64-linux]
* Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
~~~
# ruby --parser=parse.y -e "42.tap { it = it; p it }"
nil
# ruby --parser=prism -e "42.tap { it = it; p it }"
42
~~~


---Files--------------------------------
clipboard-202503081702-idzz2.png (22.6 KB)


-- 
https://bugs.ruby-lang.org/
______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/


In This Thread