Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong context in different types of eval calls #3072

Closed
jbreeden opened this issue Jan 6, 2016 · 2 comments
Closed

Wrong context in different types of eval calls #3072

jbreeden opened this issue Jan 6, 2016 · 2 comments

Comments

@jbreeden
Copy link
Contributor

jbreeden commented Jan 6, 2016

Probably easiest to demonstrate with code. I've duplicated some code, and run it in different types of eval calls. It's interesting how the type of eval and the use of string interpolation affect the value of self. In every case, it should be an instance of MyClass, but often it becomes main.

Results:

Instance eval a block (Success!)
--------------------------------

self outside of loop, no string interpolation: MyClass instance
self outside of loop, with string interpolation: MyClass instance
self inside of loop, no string interpolation: MyClass instance
self inside of loop, with string interpolation: MyClass instance

Instance eval a string
----------------------

self outside of loop, no string interpolation: MyClass instance
self outside of loop, with string interpolation: main
self inside of loop, no string interpolation: main
self inside of loop, with string interpolation: main

Instance eval a block, then eval a string
-----------------------------------------

self outside of loop, no string interpolation: main
self outside of loop, with string interpolation: MyClass instance
self inside of loop, no string interpolation: main
self inside of loop, with string interpolation: MyClass instance

Code:

class MyClass
  def inspect
    "MyClass instance"
  end
end

obj = MyClass.new

def banner(msg)
  puts
  puts msg
  puts '-' * msg.length
  puts
end

banner "Instance eval a block (Success!)"

obj.instance_eval do
  print "self outside of loop, no string interpolation: "
  puts self.inspect
  puts "self outside of loop, with string interpolation: #{self.inspect}"
  1.times do |x|
    print "self inside of loop, no string interpolation: "
    puts self.inspect
    puts "self inside of loop, with string interpolation: #{self.inspect}"
  end
end

banner "Instance eval a string"

obj.instance_eval(<<EOS, 'test', 0)
  print "self outside of loop, no string interpolation: "
  puts self.inspect
  puts "self outside of loop, with string interpolation: #{self.inspect}"
  1.times do |x|
    print "self inside of loop, no string interpolation: "
    puts self.inspect
    puts "self inside of loop, with string interpolation: #{self.inspect}"
  end
EOS

banner "Instance eval a block, then eval a string"

obj.instance_eval do
  eval <<EOS
  print "self outside of loop, no string interpolation: "
  puts self.inspect
  puts "self outside of loop, with string interpolation: #{self.inspect}"
  1.times do |x|
    print "self inside of loop, no string interpolation: "
    puts self.inspect
    puts "self inside of loop, with string interpolation: #{self.inspect}"
  end
EOS
end

I'm trying to get to the bottom of this issue, which seems to be caused by a similar mixup with the value of local variables. In that case it happens when eval-ing a string - but only if you do it in a method. I'm hoping they're related!

@jbreeden
Copy link
Contributor Author

jbreeden commented Jan 7, 2016

Thanks @matz! I'm still having trouble with the string interpolation when instance_eval'ing a string directly though.

Instance eval a block (Success!)
--------------------------------

self outside of loop, no string interpolation: MyClass instance
self outside of loop, with string interpolation: MyClass instance
self inside of loop, no string interpolation: MyClass instance
self inside of loop, with string interpolation: MyClass instance

Instance eval a string
----------------------

self outside of loop, no string interpolation: MyClass instance
self outside of loop, with string interpolation: main
self inside of loop, no string interpolation: MyClass instance
self inside of loop, with string interpolation: main

Instance eval a block, then eval a string
-----------------------------------------

self outside of loop, no string interpolation: MyClass instance
self outside of loop, with string interpolation: MyClass instance
self inside of loop, no string interpolation: MyClass instance
self inside of loop, with string interpolation: MyClass instance

@jbreeden
Copy link
Contributor Author

jbreeden commented Jan 7, 2016

Oops! Sorry... Didn't think about the string interpolation happening before the eval. That was just a bad test. Thanks very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant