Issue #12861 has been updated by bug hit.


Shyouhei Urabe wrote:
> bug hit wrote:
> > I think it would be better if super were always lexically scoped
> 
> Agreed but... What should then happen for inter-class block passing situation, like this?
> 
> ```ruby
> class Foo
>   def self.foo
>     'foo@foo'
>   end
> end
> 
> class Bar < Foo
>   def self.bar(&block)
>     define_singleton_method :foo, &block
>   end
> end
> 
> class Baz
>   def self.foo
>     Bar.bar do
>       super
>     end
>   end
> end
> 
> Baz.foo
> ```

you probably meant to call the defined :foo?

```ruby
class Foo
  def self.foo
    'foo@foo'
  end
end

class Bar < Foo
  def self.bar(&block)
    define_singleton_method :foo, &block
    send(:foo)
  end
end

class Baz
  def self.foo
    Bar.bar do
      super()
    end
  end
end

Baz.foo
```
In your example, if super were always lexically/statically bound to the method name, I suppose it would have to fail the same way instance_eval of the block fails when self is wrong (self has wrong type to call super in this context).  But that would be an understandable error.  

The solution would be to use a dynamic_super, which calls the super of the current method on the stack.  Maybe it could even be a kernel method rather than a keyword.  This way super the keyword would always be lexiacally/statically bound to the method name, and a call_super() method for meta programming, would call the super of the dynamically determined current `__method__`



----------------------------------------
Bug #12861: super in a block can be either lexically or dynamically scoped depending on how the block is invoked
https://bugs.ruby-lang.org/issues/12861#change-61039

* Author: bug hit
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
* Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN
----------------------------------------
```ruby
class Class1
  def self.foo
    'foo'
  end
  def self.method1
    'method1'
  end
end

class Class2 < Class1
  def self.foo
    bar do
      super()
    end
  end
  def self.bar(&block)
    a = block.()
    define_singleton_method :method1, &block
    b = send(:method1)
    c = block.()
    [a, b, c]
  end
end

p Class2.foo # ["foo", "method1", "foo"]
```

It doesn't seem like a good idea for a given language construct to be either lexically or dynamically scoped, depending on how its surrounding block is invoked (which is not visible at the point of definition).  I think it would be better if super were always lexically scoped, and a different keyword (dynamic_super) were always dynamically scoped



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

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>