[ruby-core:77750] [Ruby trunk Bug#12861] super in a block can be either lexically or dynamically scoped depending on how the block is invoked

From: alxtskrnk@...
Date: 2016-10-24 17:18:23 UTC
List: ruby-core #77750
Issue #12861 has been updated by bug hit.


bug hit wrote:
> 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, I suppose it would have to fail the same way instance_eval of the block (with super) 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 lexically/statically bound to the method, 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-61053

* 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>

In This Thread

Prev Next