Issue #7914 has been updated by trans (Thomas Sawyer).


@rosenfeld Maybe I approached this backwards. I just wanted to show one possible use case for supporting local vs. non-local class methods. Your in-method conditional solution works for this specific case, true. But how well does it translate to other cases? For instance, it would not work with anonymous classes. called_by_super is an interesting notion, but after some thought it feels like a make shift approach that only address part of the wider issue. The module non-local side of this is important too. And its use case is much more obvious --everywhere the included/ClassMethods hack is used.




----------------------------------------
Feature #7914: Case for local class methods
https://bugs.ruby-lang.org/issues/7914#change-36827

Author: trans (Thomas Sawyer)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


=begin
Here is a use case for local class methods.

Say we wish to give certain classes and all subclasses a special name.

  class X
    def self.special_name
      "special:#{name}"
    end
  end
  class Y < X; end
  class Z < Y; end

  Z.special_name  #=> "special:Z"

But what if Y has a unique special name?

  class Y < X
    def special_name
      'unique:Y'
    end
  end

Problem that arises:

    Z.special_name  #=> "unique:Y"  # wrong!

Currently, to solve this would require creating an additional method, e.g. `unique_name` and redefine `special_name` to first look for unique_name then fallback to default special name if non-found. It works, but adds additional complexity to API.

Nicer solution would be local class methods.

    class Y < X
      def special_name
        'unique:Y'
      end
      local :special_name
    end

    Y.special_name  #=> "unique:Y"
    Z.special_name  #=> "special:Z"

The idea being that local class methods are skipped in super/lookup chain.

This idea is not without precedence. Module class methods can be thought of as being local. So this idea has other side of the notion, that modules could have class methods that are not skipped over in the super/lookup chain. In that case we would need a term that means opposite of local, so I'll use `nonlocal`:

    module M
      def self.q; "q"; end
      nonlocal :q
    end

    class X
      include M
    end

    X.q  #=> "q"

=end



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