[#66126] Creation/Conversion methods/functions table for Ruby types — SASADA Koichi <ko1@...>
Hi,
5 messages
2014/11/07
[#66248] [ruby-trunk - Feature #10423] [PATCH] opt_str_lit*: avoid literal string allocations — normalperson@...
Issue #10423 has been updated by Eric Wong.
3 messages
2014/11/13
[#66595] [ruby-trunk - Bug #10557] [Open] Block not given when the argument is a string — bartosz@...
Issue #10557 has been reported by Bartosz Kopinski.
3 messages
2014/11/30
[ruby-core:66350] [ruby-trunk - Feature #10498] Make `loop` yield a counter
From:
franck@...
Date:
2014-11-18 16:24:40 UTC
List:
ruby-core #66350
Issue #10498 has been updated by Franck Verrot.
Robert Klemme wrote:
> > [...] I wasn't able to find a way to fine-tune this based on the block's arity as mentioned previously.
>
> That seems fairly easy:
>
> ~~~
> def lp(&b)
> return to_enum(:lp) unless b
>
> if b.arity == 0
> while true
> b[]
> end
> else
> i = 0
>
> while true
> b[i]
> i += 1
> end
> end
>
> raise "This must never happen"
> end
> ~~~
I meant in C but yes, given we could have `Kernel#loop_with_index` implemented in Ruby, it would be a no-brainer.
> > On the other hand, you'd need 4,611,686,018,427,387,903 iterations before paying the price of using `BigNum`s, which compared to the code you're having in the block would probably be more expensive than incrementing a `BigNum`.
>
> Yes, but as a user of loop you would not have a choice any more. I'd rather use the approach from above or define another method loop_with_index or use the approach with Generator and a constant. I would definitively not unconditionally provide a counter.
I get your point.
`times` does yield a counter, would you say it's the same concern?
----------------------------------------
Feature #10498: Make `loop` yield a counter
https://bugs.ruby-lang.org/issues/10498#change-50003
* Author: Franck Verrot
* Status: Open
* Priority: Normal
* Assignee: ruby-core
* Category: core
* Target version: current: 2.2.0
----------------------------------------
# Problem
Teaching Ruby, we always end up with that type of construct
```ruby
i = 0
loop do
i += 1
# do something with i....
raise StopIteration if i ...
end
```
# Solution
What I propose with this patch is making `loop` yield the iteration count:
```ruby
loop do |i|
# do something with i....
raise StopIteration if i ...
end
```
`i` starts at 0 and stops at `FIXNUM_MAX` (there's no `Float::Infinity` equivalent for integers).
# Alternate solution
`Integer#times` could work if we had an `<Integer's infinity>` object, so we would just do `<Integer's Infinity>.times { |i| ... }`.
Also, this is the very first patch I submit to Ruby, I might have done something horrible, feel free to tell me :-)
---Files--------------------------------
0001-vm_eval.c-loop-now-yields-a-incremented-counter.patch (1.74 KB)
0001-vm_eval.c-loop-now-yields-a-incremented-counter.patch (1.86 KB)
--
https://bugs.ruby-lang.org/