[ruby-core:67976] [ruby-trunk - Bug #10818] Extrange behaviour when apliying a refinement inside eval

From: hanachin@...
Date: 2015-02-03 10:06:24 UTC
List: ruby-core #67976
Issue #10818 has been updated by Seiei Higa.


> Refinements should be activated in a lexical scope, so NoMethodError shou=
ld be raised in that case.

How about this case?

``` ruby
class C; end

module M
  refine(C) do
    def foo
      42
    end
  end

  using M

  $b =3D binding
end
puts $b.eval('C.new.foo')

# result in 2.2.0:
#   42
```

[The docs of Binding](http://www.ruby-doc.org/core-2.2.0/Binding.html) says

> Objects of class Binding encapsulate the execution context at some partic=
ular place in the code and retain this context for future use. The variable=
s, methods, value of self, and possibly an iterator block that can be acces=
sed in this context are all retained.

and [docs of Binding#eval](http://www.ruby-doc.org/core-2.2.0/Binding.html#=
method-i-eval) says

> Evaluates the Ruby expression(s) in string, in the binding=E2=80=99s cont=
ext.

It's sounds good to retain refinements in binding's context.

----------------------------------------
Bug #10818: Extrange behaviour when apliying a refinement inside eval
https://bugs.ruby-lang.org/issues/10818#change-51364

* Author: Pablo Herrero
* Status: Assigned
* Priority: Normal
* Assignee: Shugo Maeda
* ruby -v: ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
When you activate a refinement inside an a string using `eval` with a bindi=
ng, the refinement is sill active the next time you call `eval` with the sa=
me binding.
Strangely enough, this will only happen if there is an assignment at the co=
de evaluated the first time. If you delete the assignment everything works =
as expected.

```ruby
module M
  refine String do
    def foobar; puts 'foobar'; end
  end
end

some_binding =3D class A; binding; end


str1 =3D <<EOF
a =3D 'something' # Without this everything works as expected
using M
'str'.foobar # Works fine
EOF

str2 =3D <<EOF
'str'.foobar # This time should fail but it doesn't
EOF

eval str1, some_binding
eval str2, some_binding
```

Acording to the [RefinmentsSpec](https://bugs.ruby-lang.org/projects/ruby-t=
runk/wiki/RefinementsSpec): "when main.using is invoked in a string given a=
s the first argument of Kernel#eval, Kernel#instance_eval, or Module#module=
_eval, the end of the scope is the end of the string."

Which contradicts with this code's behavior.



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

In This Thread

Prev Next