Issue #17649 has been updated by jeremyevans0 (Jeremy Evans).


I submitted a pull request that should fix this: https://github.com/ruby/ruby/pull/4213

----------------------------------------
Bug #17649: `defined?` invokes method once for each syntactic element around it
https://bugs.ruby-lang.org/issues/17649#change-90555

* Author: josh.cheek (Josh Cheek)
* Status: Open
* Priority: Normal
* ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin20]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
Honestly, I was surprised `defined?` works with expressions at all. I wouldn't object to this feature being removed, it leads to strange situations where it invokes methods, like below, and silently returns wrong results, if any of the methods raise. But, given that it is implemented this way, it should probably not be invoking methods multiple times like this.

```ruby
public def x
  $times_called += 1
end

def times_called
  $times_called = 0
  yield
  $times_called
end

# without `defined?`
times_called { x }           # => 1
times_called { -x }          # => 1
times_called { --x }         # => 1
times_called { ---x }        # => 1
times_called { x+0+0 }       # => 1
times_called { x.pred.pred } # => 1
times_called { x.x.x.x.x.x } # => 6

# with `defined?`
times_called { defined? x }           # => 0
times_called { defined? -x }          # => 1
times_called { defined? --x }         # => 2
times_called { defined? ---x }        # => 3
times_called { defined? x+0+0 }       # => 2
times_called { defined? x.pred.pred } # => 2
times_called { defined? x.x.x.x.x.x } # => 15
```



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>