> Is it at all possible to write an iterator, which allows assignments
> inside a block?
I'm not sure what you're looking for, but maybe this is some kind of answer
a = 1
[1,2,3].each { |i| a += i }
p a
This outputs 7 instead of 1. So we _are_ assigning to a inside a block. And
that's great! :)
> I have a vague understanding that the main obstacle is the fact
> that ``x=y'' does not involve a method invocation.
class Assignable
def initialize(val)
self.value = val
end
def value=(other)
@value = other
end
end
a = Assignable.new(5)
p a # => #<Assignable:0x4017a9b4 @value=5>
a.value = 10
p a # => #<Assignable:0x4017a9b4 @value=10>
We are calling the value= method on two occasions, at initialize and at
a.value=10.
> I am not sure if this is a bug but it certainly violates the
> ruby principle of ``least surprise''. Any thoughts?
Well, first of all you don't be specific where the 'bug' might be lurking.
So I didn't quite find it. But nevertheless the output looks ok to me. To
see why the two cases print different output, study the output of this small
example:
dyn = Array.new(3,"x")
sta = ["x","x","x"]
class Array
def inspect
"[" + self.collect { |e| e.id }.join(", ") + "]"
end
end
p dyn
p sta
Outputting:
[537644958, 537644958, 537644958]
[537644928, 537644918, 537644908]
As you can see, the Array.new(3,"x") produces an array with three elements,
and each of the elements refer to same string object. The latter points to
three different string objects (each containing same string "x").
THE reference
http://www.rubycentral.com/ref/ref_c_array.html#new
tells this:
Returns a new array, optionally with a size and initial
value (that is, anInteger references to the same anObject).
Note the wording "references to the *same* anObject).
- Aleksi