如何继承 class w\ ruby 中的属性
How to inherit class w\ properties in ruby
我是 Ruby 的新手,我来自 PHP,无法理解示例中的代码:
module Twitter
class API < Grape::API
version 'v1', using: :header, vendor: 'twitter'
format :json
prefix :api
基本上我需要继承 class 如下:
class MyAPI < Twitter::API
但在那个 MyAPI class format
、prefix
和 version
中不起作用,我不明白为什么,没有一本手册或教程不工作'不要回答我的问题。
例如format
设置为api以json格式输出结果。在 Twitter::API class 中它运行良好,但在 child 中却不适用。所以我需要在每个 child classes 上写这个不好的地方。
version
和 format
究竟是什么?它是变量(class 属性)还是 parent class 方法调用?
我假设它是一个调用并尝试 Twitter::API 像这样的东西:
def initialize
format :json
end
但是报错:
TypeError: no implicit conversion of Symbol into String
或
def initialize
self.format :json
end
NoMethodError: private method `format' called for #<MyAPI>
请尽可能详细。
您还可以指出解释它的文档吗?
format
类似于
class API
private_class_method def self.format(kind)
#...
end
end
Ruby 中的私有方法不能用显式接收器调用(前面有一个点),只能调用隐式接收器(发送到 self
的当前值)。在 class 定义中,self
是被定义的 class。这就是为什么你可以写
def self.format(...)
而不是
def API.format(...)
因此,在您的代码中,
class MyAPI < API
format :json
# ...
end
它正在 class 对象 MyAPI
上调用方法 format
,由于继承自 API
, 作为 class 正在定义 。查看 Grape 源代码,format
将(最终)在实例变量中设置一个值。让我们将其简化为 @format
(实际上并非如此,它是继承的而不是在 API
上,但是...简化示例)。我们再做一个方法,看看实例变量的值是多少。
class API
private_class_method def self.format(what)
@format = what
end
def self.peek_format
@format
end
end
现在让我们做一个子class:
class SubAPI < API
end
现在,要设置格式,我们想使用类似 API.format(:json)
的东西,但我们不能,因为它是私有的。所以我们将创建一个上下文,其中 format(:json)
自然地转到 API
:
class API
format :json
end
API.peek_format
# => :json
格式已设置。一切似乎都很好。现在让我们看看 subclass:
会发生什么
class SubAPI
format :txt
end
SubAPI.peek_format
# => :txt
但是,
API.peek_format
# => :json
方法是继承的;实例变量不是。每个 class 实例(即类型 Class
的对象)都有自己的一组实例变量,就像每个其他对象都有自己的一组实例变量一样,不与相同 [=63 的其他对象共享=].
如果你真的希望每个子class做同样的初始化,你可以这样做(虽然这不是最好的主意):
class API
private_class_method def self.format(what)
@format = what
end
def self.peek_format
@format
end
# common initialisation
private_class_method def self.initialize_class
format :json
end
# whenever we get a new subclass, run the initialisation
private_class_method def self.inherited(subclass)
subclass.instance_eval do
initialize_class
end
end
# now initialise this class too
initialize_class
end
class SubAPI < API
end
API.peek_format
# => :json
SubAPI.peek_format
# => :json
但我劝你不要这样做。如果您正在使用 MyAPI
,那么您可能没有使用 API
本身;您不需要在其中设置格式(或其他参数)。
我是 Ruby 的新手,我来自 PHP,无法理解示例中的代码:
module Twitter
class API < Grape::API
version 'v1', using: :header, vendor: 'twitter'
format :json
prefix :api
基本上我需要继承 class 如下:
class MyAPI < Twitter::API
但在那个 MyAPI class format
、prefix
和 version
中不起作用,我不明白为什么,没有一本手册或教程不工作'不要回答我的问题。
例如format
设置为api以json格式输出结果。在 Twitter::API class 中它运行良好,但在 child 中却不适用。所以我需要在每个 child classes 上写这个不好的地方。
version
和 format
究竟是什么?它是变量(class 属性)还是 parent class 方法调用?
我假设它是一个调用并尝试 Twitter::API 像这样的东西:
def initialize
format :json
end
但是报错:
TypeError: no implicit conversion of Symbol into String
或
def initialize
self.format :json
end
NoMethodError: private method `format' called for #<MyAPI>
请尽可能详细。 您还可以指出解释它的文档吗?
format
类似于
class API
private_class_method def self.format(kind)
#...
end
end
Ruby 中的私有方法不能用显式接收器调用(前面有一个点),只能调用隐式接收器(发送到 self
的当前值)。在 class 定义中,self
是被定义的 class。这就是为什么你可以写
def self.format(...)
而不是
def API.format(...)
因此,在您的代码中,
class MyAPI < API
format :json
# ...
end
它正在 class 对象 MyAPI
上调用方法 format
,由于继承自 API
, 作为 class 正在定义 。查看 Grape 源代码,format
将(最终)在实例变量中设置一个值。让我们将其简化为 @format
(实际上并非如此,它是继承的而不是在 API
上,但是...简化示例)。我们再做一个方法,看看实例变量的值是多少。
class API
private_class_method def self.format(what)
@format = what
end
def self.peek_format
@format
end
end
现在让我们做一个子class:
class SubAPI < API
end
现在,要设置格式,我们想使用类似 API.format(:json)
的东西,但我们不能,因为它是私有的。所以我们将创建一个上下文,其中 format(:json)
自然地转到 API
:
class API
format :json
end
API.peek_format
# => :json
格式已设置。一切似乎都很好。现在让我们看看 subclass:
会发生什么class SubAPI
format :txt
end
SubAPI.peek_format
# => :txt
但是,
API.peek_format
# => :json
方法是继承的;实例变量不是。每个 class 实例(即类型 Class
的对象)都有自己的一组实例变量,就像每个其他对象都有自己的一组实例变量一样,不与相同 [=63 的其他对象共享=].
如果你真的希望每个子class做同样的初始化,你可以这样做(虽然这不是最好的主意):
class API
private_class_method def self.format(what)
@format = what
end
def self.peek_format
@format
end
# common initialisation
private_class_method def self.initialize_class
format :json
end
# whenever we get a new subclass, run the initialisation
private_class_method def self.inherited(subclass)
subclass.instance_eval do
initialize_class
end
end
# now initialise this class too
initialize_class
end
class SubAPI < API
end
API.peek_format
# => :json
SubAPI.peek_format
# => :json
但我劝你不要这样做。如果您正在使用 MyAPI
,那么您可能没有使用 API
本身;您不需要在其中设置格式(或其他参数)。