我有NodeJs的背景,我是Ruby的新手,如果这个问题是个问题,请原谅。我有三节这样的课。
class Babylon::Metric::Counter < Babylon::Metric
protected
def record
# some code here
end
end
class Babylon::Metric::Gauge < Babylon::Metric
protected
def record
# some code here
end
end
它们的父类是
class Babylon::Metric
class ArgumentError < ArgumentError; end
def initialize name, category, amount
@name = name
@category = category
@amount = amount
end
def self.call name:, category:, amount:
new(name, category, amount).()
end
# What is it doing here exactly is it calling Counter or Gauge record method from here,
# based on valid method returns true or false?
def call
valid? ? record : notify
rescue => e
begin
raise Babylon::Error, e.inspect
rescue Babylon::Error => e
Babylon::Event.(event: "babylon.error", error: e)
end
end
def valid?
# do validation
end
def notify
# do some stuff
end
end
我认为调用方法可以反过来调用Counter类和Gauge类的记录方法。如果有效方法返回true,但我不知道它如何调用,因为这些都是受保护的成员?。
如果初始化父类并对其调用call
或record
方法,则会得到预期的NoMethodError
。诀窍是,父母的所有方法都可以在孩子身上使用。
这意味着,如果启动一个子类并对其调用record
,则会完全按照预期调用该子类上的记录方法。
但是,如果在子类上调用call
方法,它将使用来自父类的实现,但在子类的上下文中,这意味着在其中调用的记录方法将可用,并且不会引发错误。
在Ruby中,protected
方法只能用以下任一方法调用:
- 隐式接收器(即
say_hello
而非self.say_hello
( - 同一对象族中的显式接收器(自身和子体(
在父类中,可以看到record
是用隐式接收器调用的,这意味着该方法可以是public、protected、或private。
例如:
class Foo
def say_hello
whisper_hello # implicit receiver
end
end
class Bar < Foo
private # protected would work as well in this example
def whisper_hello
puts "(hello)"
end
end
在这个例子中,Foo.new.say_hello
将失败,因为whisper_hello
没有在父类中定义(换句话说,你可以说Foo
是一个抽象类(;但是CCD_ 13将正常工作。