[#23457] [Bug #1471] "Mutual join" deadlock detection faulty in 1.8.6 and 1.8.7 — John Carter <redmine@...>

Bug #1471: "Mutual join" deadlock detection faulty in 1.8.6 and 1.8.7

17 messages 2009/05/15

[#23483] [Bug #1478] Ruby archive — Oleg Puchinin <redmine@...>

Bug #1478: Ruby archive

29 messages 2009/05/16
[#29225] [Feature #1478] Ruby archive — Luis Lavena <redmine@...> 2010/04/02

Issue #1478 has been updated by Luis Lavena.

[#30345] Re: [Feature #1478] Ruby archive — "NAKAMURA, Hiroshi" <nakahiro@...> 2010/05/21

On Fri, Apr 2, 2010 at 17:13, Luis Lavena <redmine@ruby-lang.org> wrote:

[#30346] Re: [Feature #1478] Ruby archive — Jonathan Nielsen <jonathan@...> 2010/05/21

> Thanks for your comment.

[#30347] Re: [Feature #1478] Ruby archive — Jonathan Nielsen <jonathan@...> 2010/05/21

OK Hiroshi, I read some of the comments earlier in the thread that I

[#30355] Re: [Feature #1478] Ruby archive — Caleb Clausen <vikkous@...> 2010/05/21

On 5/20/10, Jonathan Nielsen <jonathan@jmnet.us> wrote:

[#30364] Re: [Feature #1478] Ruby archive — Benoit Daloze <eregontp@...> 2010/05/22

Hi,

[#23505] [Bug #1494] tempfile#unlink may silently fail on windows — Nicholas Manning <redmine@...>

Bug #1494: tempfile#unlink may silently fail on windows

19 messages 2009/05/19

[#23572] [Bug #1525] Deadlock in Ruby 1.9's VM caused by ConditionVariable.wait and fork? — Hongli Lai <redmine@...>

Bug #1525: Deadlock in Ruby 1.9's VM caused by ConditionVariable.wait and fork?

27 messages 2009/05/27

[#23595] Meaning of RUBY_PLATFORM — Rick DeNatale <rick.denatale@...>

The RUBY_PLATFORM constant is documented in the latest Pickaxe as "The

17 messages 2009/05/28
[#23596] Re: Meaning of RUBY_PLATFORM — Luis Lavena <luislavena@...> 2009/05/28

On Thu, May 28, 2009 at 3:41 PM, Rick DeNatale <rick.denatale@gmail.com> wrote:

[#23602] Re: Meaning of RUBY_PLATFORM — Rick DeNatale <rick.denatale@...> 2009/05/28

On Thu, May 28, 2009 at 2:52 PM, Luis Lavena <luislavena@gmail.com> wrote:

[#23608] Re: Meaning of RUBY_PLATFORM — Luis Lavena <luislavena@...> 2009/05/28

On Thu, May 28, 2009 at 7:08 PM, Rick DeNatale <rick.denatale@gmail.com> wrote:

[#23609] Re: Meaning of RUBY_PLATFORM — Rick DeNatale <rick.denatale@...> 2009/05/29

On Thu, May 28, 2009 at 7:22 PM, Luis Lavena <luislavena@gmail.com> wrote:

[ruby-core:23630] Expected Behaviour of Modifying an Iterator in the Block to Which it Yields?

From: Run Paint Run Run <runrun@...>
Date: 2009-05-30 01:38:52 UTC
List: ruby-core #23630
Hi,

While writing some specifications for RubySpec, I've encountered an issue that
I'd appreciate clarification on: What is the expected behaviour of an iterator
if it is modified inside of the block to which it yields?

For example, the following enters an infinite loop because it appends to the
Array being iterated over for each iteration. Here, the number of iterations
can be increased from within the block.

>> a = (1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> a.each { |e| a << 0 }
# Infinite loop

Conversely, calling a.reject!(true) inside the iterator block truncates the
Array, halting iteration:

>> a = (1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> a.each { |e| a.reject!{true}; p e }
1
=> []

Prepending to an Array, increases the number of iterations:

>> @prepend = true
=> true
>> a=(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> a.each {|e| a.unshift(0) if @prepend; @prepend = false; p e}
1
1
2
3
4
5
6
7
8
9
10
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

When iterating over an Array, deleting the element that is being yielded
reduces the number of iterations::

>> a=(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> a.each { |e| a.delete(e); p e }
1
3
5
7
9
=> [2, 4, 6, 8, 10]

However, with a Hash:

>> h={:foo=>:bar, :glark => :quark}
=> {:foo=>:bar, :glark=>:quark}
>> h.each_key{|k| h.delete(k); p k}
:foo
:glark
=> {}

In the following example assigning to a[-1] changes the final element yielded:

>> a=(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> a.each {|e| a[-1] = 0; p e }
1
2
3
4
5
6
7
8
9
0
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

In this example, assigning to the object being iterated over while inside the
block doesn't affect the iteration.

>> a = (1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> a.each { |e| a = 0; p e }
1
2
3
4
5
6
7
8
9
10
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Similarly, changing the 0th element of the Array doesn't have any effect:

>> a=(1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> a.each { |e| a[0] = 0; p e }
1
2
3
4
5
6
7
8
9
10
=> [0, 2, 3, 4, 5, 6, 7, 8, 9, 10]

The principles I derive from this are:

The abstraction of iterating over Arrays as collections of objects with #each
is broken somewhat because it is revealed that it's the Array's index that is
used in the iteration. So, if one assigns to an index of the Array that has
already been iterated over, the new object will not be yielded to the block.
However, the opposite case will yield the new object. The reliance on indicies
is most apparent when considering the #unshift example, because it results in
the original 0th element being yielded twice, and the new 0th element not
being yielded at all.

In both cases, truncating the iterator reduces the number of iterations, and
appending to the iterator increases the same. In both cases, changing the type
of the iterator from inside the block has no effect on the iteration.

However, these principles don't hold when considering other types of
iterators. For example, using String#each_char, and appending to the String
from inside the block, does not affect the iteration whatsoever. Similarly,
assigning to an index of the String has no effect on the iteration.

There are clearly more complex examples, but I think these are enough to
explain the situation. I'm wondering whether this class of behaviour should be
considered defined or undefined. and if the former, whether there are any
general principles at work here. What's the Right Thing to do in cases where
the iterator is modified from inside the block it yields to? Or is the answer
simply that the current behaviour is correct by definition? :-)

-- 
Run Paint Run Run
<http://vim.runpaint.org/>

In This Thread

Prev Next