INTRODUCTION
As some of you no doubt know by this point, I am in the process of
validating a medium large (~14,000 line) application on 1.8.1 & 1.8.2
(this is the same one I was working on last spring, when I was brining
it from 1.6.8 & other three other languages into pure ruby 1.8.0).
I have found what appears to be a bug. Prior to digging in to the
ruby source, I'm wondering if anyone else is working this, and/or if
anyone has any thoughts on it.
SAMPLE CODE
The following example program exhibits the bug. A routine which
takes one or more arguments, any of which may be of any type, is
implemented as both a procedure and a Proc object. The semantics should
be consistent and equivalent, regardless of the version used or the
class or number of the actual parameters.
def test(head,*rest)
print "head = #{head.inspect} "
print "rest = #{rest.inspect}\n"
end
test2 = Proc.new { |head,*rest|
print "head = #{head.inspect} "
print "rest = #{rest.inspect}\n"
}
test(:a,:b,:c)
test([:a],:b,:c)
test([:a,:b],:c)
test([:a,:b,:c])
print "-----------------\n"
test2.call(:a,:b,:c)
test2.call([:a],:b,:c)
test2.call([:a,:b],:c)
test2.call([:a,:b,:c])
EXPECTED RESULTS (actual, on 1.8.0)
Under 1.8.0, we get exactly what we would expect under all tested
conditions--note that it always correctly distinguishes the first
argument from the rest, and produces the same result regardless of which
form is used:
head = :a rest = [:b, :c]
head = [:a] rest = [:b, :c]
head = [:a, :b] rest = [:c]
head = [:a, :b, :c] rest = []
-----------------
head = :a rest = [:b, :c]
head = [:a] rest = [:b, :c]
head = [:a, :b] rest = [:c]
head = [:a, :b, :c] rest = []
ACTUAL RESULTS (on 1.8.1 & 1.8.2)
But under 1.8.1 & 1.8.2 the Proc object produces aberrant results
in the special case of a single array parameter, acting as if the actual
parameter had been prefixed with an "*" when in fact it was not:
head = :a rest = [:b, :c]
head = [:a] rest = [:b, :c]
head = [:a, :b] rest = [:c]
head = [:a, :b, :c] rest = []
-----------------
head = :a rest = [:b, :c]
head = [:a] rest = [:b, :c]
head = [:a, :b] rest = [:c]
head = :a rest = [:b, :c]
^^^^^^^^^^^^^^^^^ incorrect
Thoughts? In the absence of helpful pointers I will try to trace
it in the code myself, but I don't want to waste a lot of time if this
is a known issue being worked by someone else (but I'm, as always,
willing to pitch in and help if needed).
-- Markus