我是Ruby的新手,我来自PHP,无法理解来自示例的代码:
module Twitter
class API < Grape::API
version 'v1', using: :header, vendor: 'twitter'
format :json
prefix :api
基本上我需要继承该类,如下所示:
class MyAPI < Twitter::API
但是在那个MyAPI课程format
,prefix
和version
没有工作,我无法理解为什么,也没有任何手册或教程没有。回答我的问题。
例如format
正在设置api以json格式输出结果。在Twitter :: API类中,它运行良好,但在子类中,它并不适用。因此,我需要在每个儿童班上写下这不是好事。
version
和format
实际上是什么?它是变量(类属性)还是它的父类方法调用?
我假设它是一个电话,并在Twitter :: API中尝试类似:
def initialize
format :json
end
但是得到一个错误:
TypeError:没有将Symbol隐式转换为String
或
def initialize
self.format :json
end
NoMethodError:私有方法`格式&#39;呼叫#&lt; MyAPI&gt;
请尽可能详细。 你能指点我解释它的文件吗?
答案 0 :(得分:2)
format
就像是
class API
private_class_method def self.format(kind)
#...
end
end
Ruby中的私有方法不能使用显式接收器(前面有一个点)调用,只能使用隐式调用(发送到self
的当前值)。在类定义中,self
是要定义的类。这就是你可以写
def self.format(...)
而不是
def API.format(...)
因此,在您的代码中,
class MyAPI < API
format :json
# ...
end
它正在类对象format
上调用方法MyAPI
,因为正在定义类,因为API
,的继承。查看Grape源,format
将(最终)在实例变量中设置一个值。我们将它简化为@format
(它实际上不是那个,它是继承的而不是API
,但是......简化了示例)。我们还要制作另一种方法,看看实例变量的值是什么。
class API
private_class_method def self.format(what)
@format = what
end
def self.peek_format
@format
end
end
现在让我们创建一个子类:
class SubAPI < API
end
现在,要设置格式,我们希望使用类似API.format(:json)
的内容,但我们不能,因为它是私有的。因此,我们将创建format(:json)
自然转到API
的上下文:
class API
format :json
end
API.peek_format
# => :json
格式已设置。一切似乎都很好。现在让我们看看子类会发生什么:
class SubAPI
format :txt
end
SubAPI.peek_format
# => :txt
但是,
API.peek_format
# => :json
方法是遗传的;实例变量不是。每个类实例(即类型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
本身;您不需要在其中设置格式(或其他参数)。