Project

General

Profile

Actions

Feature #7914

open

Case for local class methods

Added by trans (Thomas Sawyer) about 11 years ago. Updated about 6 years ago.

Status:
Open
Target version:
-
[ruby-core:52701]

Description

=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

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) about 11 years ago

This doesn't seem to be supported by any OO concept I've heard about and basically breaks the conceptual inheritance model in OO in my opinion. I wouldn't like to have to debug a code that behaved like this. It would make understanding an existent code base much harder in my opinion. Don't you think so?

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) about 11 years ago

What about the code below?

class Y < X
def special_name
self.class.name == 'Y' ? 'unique:Y' : super
end
end

Updated by rosenfeld (Rodrigo Rosenfeld Rosas) about 11 years ago

Maybe you could ask for some special method/keyword to know if the class is the same as the declared one (instead of some inheriting class):

def special_name
local_class? ? 'unique:Y' : super
end

Or instead of "local_class" you could ask if it has been called as a "super" method:

def special_name
called_by_super? ? super : 'unique:Y'
end

Actions #4

Updated by ko1 (Koichi Sasada) about 11 years ago

  • Assignee set to matz (Yukihiro Matsumoto)
  • Target version changed from 2.1.0 to 2.6

(I don't have any idea about this ticket. but I feel the name `local' recall perl)

Updated by nobu (Nobuyoshi Nakada) about 11 years ago

It seems trivial and usually avoidable.

I guess it could achieve with Module#using.

Updated by trans (Thomas Sawyer) about 11 years ago

@rosenfeld (Rodrigo Rosenfeld Rosas) 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.

Updated by funny_falcon (Yura Sokolov) about 11 years ago

Thomas Sawyer, you are the language troll, IMHO.

(But, maybe I'm too)

Everyone else, excuse me for not being polite.
23.02.2013 12:17 пользователь "trans (Thomas Sawyer)"
написал:

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

@rosenfeld (Rodrigo Rosenfeld Rosas) 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/

Actions #8

Updated by naruse (Yui NARUSE) about 6 years ago

  • Target version deleted (2.6)
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0