Project

General

Profile

Actions

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.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:113829]

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)

Updated by ufuk (Ufuk Kayserilioglu) over 1 year ago

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))))
    ))
  )
)

Updated by jeremyevans0 (Jeremy Evans) over 1 year ago

  • 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

Updated by andrykonchin (Andrew Konchin) over 1 year ago

Ah, I see. Thank you.

Actions

Also available in: Atom PDF

Like0
Like1Like0Like0