Bug #19721
closed
IO#timeout= can be called without required argument
Added by andrykonchin (Andrew Konchin) over 1 year ago.
Updated over 1 year ago.
Description
f = File.open("a.txt", "w")
f.timeout=() # => nil
IO#timeout=
requires an argument (or it's supposed to require it) but if it's called as a method it seems the check is skipped and missing argument is treated as nil
value.
If it's called with #send
- then argument presence is checked:
f.send :"timeout="
# ...:in `timeout=': wrong number of arguments (given 0, expected 1) (ArgumentError)
I believe the syntax f.timeout=()
is not calling the timeout=
method with no parameters, but instead it is assigning ()
to f.timeout
attribute. Since ()
in Ruby evaluates to nil
(because it is an empty subexpression), in essence, that line should be equivalent to f.timeout = nil
. That's why you get the nil
value.
You can check that this expression gets turned into an assigment by looking at the AST generated from f.timeout=()
on https://ruby-syntax-tree.github.io/:
(program
(statements
((assign
(field (vcall (ident "f")) (period ".") (ident "timeout"))
(paren (statements ((void_stmt))))
))
)
)
- Status changed from Open to Rejected
All assignment methods called via recv.method =
are called with one argument. ()
is translated to nil
by the compiler, because it is an expression that is evaluated to nil
:
eval('()')
# => nil
Also available in: Atom
PDF
Like0
Like1Like0Like0