Logo

TIL: Get rid of anonymous eval calls

While reviewing the changelog of Psych I stumbled upon a commit: “Get rid of anonymous eval calls”

Checking the diff I saw some hackery which spiked my interests:

- class_eval <<~RUBY
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1

This raised my eyebrows a bit and after some investigation (e.g. searching SO) I found this explanation:

# foo.rb
instance_eval <<-RUBY, __FILE__, __LINE__ + 1
  def foo
    a = 123
    b = :abc
    a.send b
  end
RUBY
foo
# w/o
$ ruby foo.rb
Traceback (most recent call last):
  1: from foo.rb:9:in `<main>'
(eval):4:in `foo': undefined method `abc' for 123:Integer (NoMethodError)

# w/
$ ruby foo.rb
Traceback (most recent call last):
  1: from foo.rb:9:in `<main>'
foo.rb:5:in `foo': undefined method `abc' for 123:Integer (NoMethodError)

Refs

H/T: https://stackoverflow.com/a/2496240/234171 H/T: https://github.com/ruby/psych/commit/38871ad4e5e3b367256ac0a950b2ed7eb0335091