# Binding#eval issue

**URL:** <https://www.ruby-forum.com/t/binding-eval-issue/183906>\
**Category:** Ruby\
**Created:** [February 22, 2010, 3:16pm UTC](https://www.ruby-forum.com/t/binding-eval-issue/183906 "2010-02-22T15:16:38Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [February 22, 2010, 3:16pm UTC](https://www.ruby-forum.com/t/binding-eval-issue/183906/1 "2010-02-22T15:16:38Z")

</div>

I have the following extensions to Binding:

class Binding

```
# Returns line number of the binding.
def __LINE__
  eval(" __LINE__")
end

# Returns file name of the binding.
def __FILE__
  eval(" __FILE__")
end

```

end

The work fine in 1.8.7 (or lower when you define Binding#eval), but  
fails in 1.9 where it returns “(eval)” instead of the file name and  
nothing at all for the line number.

Any idea on how to fix? Should this be considered a 1.9 bug?

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [February 22, 2010, 5:46pm UTC](https://www.ruby-forum.com/t/binding-eval-issue/183906/2 "2010-02-22T17:46:07Z")

</div>

Thomas S. wrote:

> I have the following extensions to Binding:
> 
> class Binding
> 
> ```
> # Returns line number of the binding.
> def __LINE__
> eval(" __LINE__")
> end
> 
> # Returns file name of the binding.
> def __FILE__
> eval(" __FILE__")
> end
> 
> ```
> 
> end
> 
> The work fine in 1.8.7

I tried this, and was surprised to find that 1.8.7 makes a special case  
of eval inside an instance method of Binding:

$ irb --simple-prompt

> > RUBY\_VERSION  
> > =\> “1.8.7”
> 
> > RUBY\_PATCHLEVEL  
> > =\> 174
> 
> > class Binding; def **LINE** ; eval “ **LINE** ”; end; end  
> > =\> nil
> 
> > class Binding; def **FILE** ; eval “ **FILE** ”; end; end  
> > =\> nil
> 
> > binding. **LINE**  
> > =\> 6
> 
> > binding. **LINE**  
> > =\> 7
> 
> > binding. **FILE**  
> > =\> “(irb)”
> 
> > binding. **FILE**  
> > =\> “(irb)”

This is particularly surprising given that instance\_eval doesn’t show  
this behaviour:

> > binding.instance\_eval “ **LINE** ”  
> > =\> 1
> 
> > binding.instance\_eval “ **LINE** ”  
> > =\> 1
> 
> > binding.instance\_eval “ **FILE** ”  
> > =\> “(eval)”
> 
> > binding.instance\_eval “ **FILE** ”  
> > =\> “(eval)”

**FILE** is the filename where the source being executed is found. When  
eval’ing from a string, the source is not in any particular file and so  
I’d always expect “(eval)” to be returned, and **LINE** to be relative  
to the start of the string, unless you pass file and/or line numbers as  
extra args to eval.

In ruby 1.9.2 this works as I’d expect:

$ irb19 --simple-prompt

> > RUBY\_REVISION  
> > =\> 24186
> 
> > class Binding; def **LINE** ; eval “ **LINE** ”; end; end  
> > =\> nil
> 
> > class Binding; def **FILE** ; eval “ **FILE** ”; end; end  
> > =\> nil
> 
> > binding. **LINE**  
> > =\> 1
> 
> > binding. **LINE**  
> > =\> 1
> 
> > binding. **FILE**  
> > =\> “(eval)”
> 
> > binding. **FILE**  
> > =\> “(eval)”

So I’d say that 1.8.7 is the anomoly.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [February 22, 2010, 6:49pm UTC](https://www.ruby-forum.com/t/binding-eval-issue/183906/3 "2010-02-22T18:49:08Z")

</div>

On Feb 22, 11:46 am, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I tried this, and was surprised to find that 1.8.7 makes a special case  
> of eval inside an instance method of Binding:

Right. I thought that was idea because you want to know about the  
binding, not the instance of Binding.

> > > binding. **LINE**  
> > > binding.instance\_eval “ **LINE** ”  
> > > eval’ing from a string, the source is not in any particular file and so  
> > > class Binding; def **FILE** ; eval “ **FILE** ”; end; end
> 
> So I’d say that 1.8.7 is the anomoly.

In that case there would be no way to define these manually. And I  
would need to request that Binding support **LINE** and **FILE** in  
core.

But I’m not so sure, because there has to be a way to access the  
binding itself or what is the point? Perhaps Binding needs a special  
method, ie. #binding\_eval, which would eval as if in the binding.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [February 22, 2010, 6:56pm UTC](https://www.ruby-forum.com/t/binding-eval-issue/183906/4 "2010-02-22T18:56:09Z")

</div>

On 2/22/2010 10:48 AM, Intransition wrote:

> In that case there would be no way to define these manually. And I  
> would need to request that Binding support **LINE** and **FILE** in  
> core.
> 
> But I’m not so sure, because there has to be a way to access the  
> binding itself or what is the point? Perhaps Binding needs a special  
> method, ie. #binding\_eval, which would eval as if in the binding.

You can just pass your binding to eval. See:  
[http://ruby-doc.org/core/classes/Kernel.html#M005922](http://ruby-doc.org/core/classes/Kernel.html#M005922)

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [February 22, 2010, 7:05pm UTC](https://www.ruby-forum.com/t/binding-eval-issue/183906/5 "2010-02-22T19:05:31Z")

</div>

On Feb 22, 12:54 pm, Walton H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > But I’m not so sure, because there has to be a way to access the  
> > binding itself or what is the point? Perhaps Binding needs a special  
> > method, ie. #binding\_eval, which would eval as if in the binding.
> 
> You can just pass your binding to eval. See:[module Kernel - RDoc Documentation](http://ruby-doc.org/core/classes/Kernel.html#M005922)

That’s how the above works actually, Binding#eval is defined as:

class Binding  
def eval(str)  
Kernel.eval(str, self)  
end  
end
