2014-01-30 81 views
0

我試圖實現一個時髦的版本的方法鏈接。每個函數調用後返回的類的實例很容易,你只是做在ruby中返回包含對象實例

def chainable_method 
    some_code() 
    self 
end 

我的想法是,你可以調用的方法依賴於以前的方法調用。我試圖通過返回屬於包含對象的對象來實現此目的。包含的對象將有一些特殊的方法,然後實現method_missing返回包含對象的實例。

編輯:子對象有一些與它相關的狀態,應該在其本身,而不是父對象。以前可能並不清楚爲什麼我只需要一個完整的方法調用實例。

super在這種情況下是不相關的,因爲包含的對象不會從包含對象繼承,我不想在包含的對象上調用包含對象的方法 - 我想調用包含對象的方法包含對象本身。我想要包含的對象,而不是包含的對象類。

不知道這是否可能。

編輯:重寫所有使用「包含/包含對象」而不是完全不正確的父/子對象。 另外,我使用1.9.3,如果這很重要。版本不重要,如果需要,我可以更改。

我的解釋可能不清楚。這裏是代碼:

class AliasableString 
    def initialize(string) 
     @string = string 
    end 

    def as(aka) 
     @aka = aka 
    end 

    def has_aka? 
     [email protected]? 
    end 

    # alias is a reserved word 
    def aka 
     @aka 
    end 

    def to_s 
     @string + (self.has_aka? ? (" as " + @aka) : "") 
    end 
end 

class Query 
    def initialize 
     @select_statements = Array.new 
    end 

    def select(statement) 
     select_statement = AliasableString.new(statement) 
     @select_statements.push(select_statement) 
     select_statement 
    end 

    def print 
     if @select_statements.size != 0 
      puts "select" 
      @select_statements.each_with_index {| select, i| 
       puts select 
      } 
     end 
    end 
end 

# Example usage 

q0 = Query.new 

q0.select("This is a select statement") 
    .select("Here's another one") 
     .as("But this one has an alias") 
    .select("This should be passed on to the parent!") 

q0.print 

我還沒有完全實現打印。 AliasableString需要將@string和@aka分開,以便稍後將它們分開。

+0

發佈父類和子類。 – jcm

+0

沒有「父實例」。只有實例。要麼你想返回'Parent.new'或者你有一個父實例,並且可以返回它。 – mudasobwa

+0

'子對象不會繼承父'''我想要父實例,而不是父類'... wat。 – jkrmr

回答

2

首先,在Query實例中包含哪類對象並不重要。在「示例用法」部分中顯示的所有語法在Query中進行了適當的定義。查詢實例中包含的對象的唯一要求是它們響應as(或某種類似的方法)。你在這裏有什麼像狀態機,但唯一真正重要的狀態是某個對象佔據了select_statements陣列中的最後一個位置。這是我會怎麼構建這個(再次,主要基於在結束你的榜樣,我恐怕不能完全按照你最初的解釋):

class Query 
    # ... initialize, etc. 

    def select(statement, statement_class = AliasableString) 
    select_statements << statement_class.new(statement) 
    self 
    end 

    def as(aka) 
    # this will only ever be used on the most recent statement added 
    statement_to_alias = select_statements.last 

    # throw an error if select_statements is empty (i.e., :last returns nil) 
    raise 'You must add a statement first' unless statement_to_alias 

    # forward the message on to the statement 
    statement_to_alias.as(aka) 

    # return the query object again to permit further chaining 
    self 
    end 
end 

AliasableString並不需要知道有關的事Query;它所需要做的就是對as作出適當的迴應。

+0

這是有效的,它比我能想出的任何其他選項更有意義/更簡單。我會去這個。謝謝! 我可以看到的唯一問題是,如果多個對象同時在一個查詢上運行(例如,使用線程),這可能會中斷,但我的最終目標只是自動生成真正重複的HiveQL查詢。我不可能想到任何真實的生活情況,這將成爲一個問題。 –

相關問題