首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从模块中访问类的包含命名空间

从模块中访问类的包含命名空间
EN

Stack Overflow用户
提问于 2010-03-20 03:22:26
回答 3查看 2K关注 0票数 3

我正在开发一个模块,其中包括将一些通用的“finder”类型功能添加到您混合到的类中。问题:出于方便和美观的原因,我想将类之外的一些功能包括在与类本身相同的范围内。

例如:

代码语言:javascript
运行
复制
class User
  include MyMagicMixin
end

# Should automagically enable:

User.name('Bob')   # Returns first user named Bob
Users.name('Bob')  # Returns ALL users named Bob 
User(5)            # Returns the user with an ID of 5
Users              # Returns all users

我可以在这些方法中完成功能,没有问题。案例1 (User.name('Bob'))很简单。然而,案例2-4要求能够在User之外创建新的类和方法.Module.included方法允许我访问类,但不允许访问它的包含作用域。没有简单的“父”类型方法,我可以在类或模块上看到。(对于命名空间,我的意思是,不是超类或嵌套模块。)

我认为最好的方法是对类的#name进行字符串解析,以打破其命名空间,然后将字符串转换为常量。但这似乎很笨拙,考虑到这是Ruby,我觉得应该有一种更优雅的方式。

有人有主意吗?还是我只是为了自己的利益太聪明了?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-20 15:20:43

在您的示例中,User只是指向Class对象的一个常量。当包含MyMagicMixin时,可以轻松地创建另一个常量指针:

代码语言:javascript
运行
复制
module MyMagicMixin
  class <<self
    def self.included(klass)
      base.extend MyMagicMixin::ClassMethods
      create_pluralized_alias(klass)
    end

    private

    def create_pluralized_alias(klass)
      fq_name = klass.to_s
      class_name = fq_name.demodulize
      including_module = fq_name.sub(Regexp.new("::#{class_name}$", ''))
      including_module = including_module.blank? ? Object : including_module.constantize
      including_module.const_set class_name.pluralize, klass
    end
  end

  module ClassMethods
    # cass methods here
  end
end

当然,这并不能回答你是否应该做这样的事情。

票数 1
EN

Stack Overflow用户

发布于 2010-03-20 04:02:50

我倾向于变得太聪明。

即使有一个优雅的解决方案,在中包含一个模块(一个在之外创建类的类)似乎也很奇怪。

票数 3
EN

Stack Overflow用户

发布于 2010-03-20 07:51:14

这是一个有时会出现在邮件列表上的问题。这也是Rails中出现的一个问题。解决方案是,正如您已经怀疑的,基本上是Regexp咀嚼。

但是,还有一个更根本的问题:在Ruby中,类没有名称!和其他类一样,类只是一个对象。您可以将其赋值给实例变量、局部变量、全局变量、常量,甚至根本不将其赋值给任何东西。Module#name方法基本上只是一种方便的方法,其工作方式如下:它查看定义的常量列表,直到找到指向接收方的常数。如果它找到了一个,它会返回它能找到的第一个,否则它会返回nil

因此,这里有两种失效模式:

代码语言:javascript
运行
复制
a = Class.new
a.name # => nil
B = a
B.name # => "B"
A = B
A.name # => "B"

  • 一个类可能根本没有名称一个类可能有多个名称,但是Module#name只返回它找到的

的第一个名称

现在,如果有人试图调用As来获取A的列表,他们会很惊讶地发现这个方法并不存在,但是他们可以调用Bs来获得相同的结果。

这在现实中确实发生了。例如,在MacRuby中,String.name返回NSMutableStringHash.name返回NSMutableDictionaryObject.name返回NSObject。这是因为MacRuby将runtime和Objective运行时集成到一个运行库中,而且由于目标-C可变字符串的语义与runtime完全相同,所以runtime类的整个实现实际上是一行:String = NSMutableString。由于MacRuby位于Objective之上,这意味着Objective首先启动,这意味着NSMutableString首先被插入符号表,这意味着它首先由Module#name找到。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2481775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档