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:

The string is evaled to create the function. The class_eval/instance_eval function uses the __FILE__ and __LINE__ to add debug information. (edited)

Which results in change of the following statement snippet

  $ 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)
+ foo.rb:5:in `foo': undefined method `abc' for 123:Integer (NoMethodError)


Used code

# foo.rb
instance_eval <<-RUBY, __FILE__, __LINE__ + 1
  def foo
    a = 123
    b = :abc
    a.send b