Ruby 中嵌套类如何访问外部类中的方法?
def class A
def a
raise "hi" #can't be reached
end
class B
def b
a() #doesn't find method a.
end
end
end
我想从 b 调用 a 并引发异常。我该怎么办?
def class A
def a
raise "hi" #can't be reached
end
class B
def b
a() #doesn't find method a.
end
end
end
I want to invoke a from b and raise the exception. How can I?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
Ruby 没有嵌套类。
继承行为的唯一方法是通过继承。
如果您希望代码正常工作,则需要使用支持嵌套类的语言。虽然这是一个令人难以置信的简洁而强大的功能,但不幸的是,我只知道两种具有嵌套类的语言:
我不知道还有其他的。
Java 有一个称为嵌套类的构造,但它们有一些不幸的设计限制。
在上面的示例中,嵌套在
A
中的不是 类B
,而是常量B
嵌套在A
内。想一想:现在,该类有两个名称:
A::B
和C
。很明显,C
是全局的,并且不嵌套在A
内。 (嗯,实际上,C
嵌套在Object
中,因为也没有真正的全局常量,但这不是重点。)但是自从C
code> 和A::B
是同一个类,显然不能既嵌套又不嵌套。唯一合乎逻辑的结论是类本身不是嵌套的。嵌套类的定义特征是方法查找沿着两个维度进行:沿着继承链向上,以及通过嵌套向外查找。与 99.9% 的所有 OO 语言一样,Ruby 只支持前者。 (从某种意义上说,嵌套类不仅继承其超类的功能,还继承其周围类的功能。)
Ruby doesn't have nested classes.
The only way to inherit behavior is, well, via inheritance.
If you want your code to work, you need to use a language which supports nested classes. While this is an incredibly neat and powerful feature, I unfortunately know of only two languages that have nested classes:
I don't know of any other.
Java has a construct called nested classes, but they have some unfortunate design limitations.
In your example above, it's not the class
B
that is nested insideA
, it is the constantB
that is nested insideA
. Think about this:Now, the class is available under two names:
A::B
andC
. It should be immediately obvious thatC
is global and not nested insideA
. (Well, actually,C
is nested insideObject
, because there aren't really global constants either, but that's beside the point.) But sinceC
andA::B
are the same class, it obviously cannot be both nested and not nested. The only logical conclusion is that the class itself isn't nested.The defining feature of nested classes is that method lookup goes along two dimensions: up the inheritance chain, and outwards through the nesting. Ruby, like 99.9% of all OO languages, only supports the former. (In some sense, nested classes inherit not only the features of their superclass, but also the features of their surrounding class.)
这只是为了好玩:
This is just for the lulz:
我通常会做这样的事情:
I typically do something like this:
如果您希望嵌套类扩展外部类,请这样做:
If you want then nested class to extend the outer class, then do so:
嗯,根据您的具体情况,实际上有一个解决方案,而且是一个非常简单的解决方案。 Ruby 允许捕获对象未捕获的方法调用。因此,对于您的示例,您可以这样做:
那么如果您这样做:
您会得到:
这可能是一种更简单的方法来制作类似 SubController 的东西,它只处理某些活动,但可以轻松调用基本控制器方法(您可能想要发送不过,父控制器作为初始化程序中的参数)。
显然,应该谨慎使用它,如果你到处使用它,它真的会让人感到困惑,但它对于简化你的代码来说确实很棒。
Well depending on your circumstances there is actually a solution, a pretty easy one at that. Ruby allows the catching of method calls that aren't captured by the object. So for your example you could do:
So then if you do this:
you get:
It is probably an easier way to make something like a SubController that only handles certain activities, but can easily call basic controller methods (You would want to send in the parent controller as an argument in the initializer though).
Obviously this should be used sparingly, and it can really get confusing if you use it all over the place, but it can be really great to simplify your code.
您可以使用 ActiveSupport 中的
module_parent
、module_parent_name
、module_parents
等方法来获取外部模块,例如:You can use methods like
module_parent
,module_parent_name
,module_parents
from ActiveSupport to get outer modules, eg.:a
应该是类A
的类方法吗?如果您想将其保留为实例方法,显然您需要在实例上调用它,例如
A.new.a
。Was
a
supposed to be a class method for classA
?If you want to keep it as an instance method, you'll obviously have call to it on an instance, like for example
A.new.a
.