2016-02-04 90 views
0

紅寶石\性能我是新我來自PHP,不能從樣本明白代碼:如何繼承類W的紅寶石

module Twitter 
    class API < Grape::API 
    version 'v1', using: :header, vendor: 'twitter' 
    format :json 
    prefix :api 

Example from here

基本上我需要繼承類如下:

class MyAPI < Twitter::API 

但在MyAPI類formatprefixversion不工作,我不明白爲什麼沒有人馬努al或教程不回答我的問題。

例如format正在設置api以json格式輸出結果。在Twitter :: API類中,它運行良好,但在兒童中卻不適用。所以我需要在每個孩子班上寫這些不好的東西。

什麼versionformat實際上是?它是變量(類屬性)還是它的父類方法調用?

我是假設,這是一個電話,並嘗試在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>

請儘可能詳細。 你也可以指向我的文檔,它在哪裏被解釋?

+3

他們是方法調用,可能會設置一些屬性。你的意思是「在MyAPI類'格式','前綴'和'版本'不起作用」?他們不提出任何錯誤,他們是完全合法的代碼。請演示它們的工作方式(代碼和錯誤消息或該代碼表現出的不良行爲)。 – Amadan

+1

括號是可選的,所以'format(:json)'和'format:json'是一樣的。 –

+0

@Amadan例如'format'設置api以json格式輸出結果。在Twitter :: API類中,它運行良好,但在兒童中卻不適用。 – Yaroslav

回答

2

format是一樣的東西在Ruby中

class API 
    private_class_method def self.format(kind) 
    #... 
    end 
end 

私有方法不能明確的接收器被稱爲(與他們前一個點),只有一個隱(發送到self當前值)。在類定義中,self是正在定義的類。這就是爲什麼你可以寫

def self.format(...) 

代替

def API.format(...) 

因此,在你的代碼,

class MyAPI < API 
    format :json 
    # ... 
end 

它調用方法format類對象MyAPI上,憑藉繼承自API,,因爲該類正在定義。看葡萄來源,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;您不需要在其中設置格式(或其他參數)。

+0

謝謝你爲我解釋一些基礎知識。事情現在更清楚。雖然它不能解決我的問題,但我接受它作爲正確的答案,因爲它會幫助我實現我確切需要的東西。我正在做一些像ApplicationController模式。不僅「格式化」這種情況。我需要做一些認證和其他所有「控制器」通用的東西(比如再次輸出格式) – Yaroslav