2012-02-23 30 views
1

我只有一個模糊的概念在這個措辭,這樣的問題需要:保持一個實例變量作爲一個實例變量,而不是其內容

我有一組我路過我的軌控制器上的值定期到一個小部件,每頁之間略有不同,從我傳遞給它。這對每一個控制器都開始變得笨拙,所以我添加了一個小類來幫助連接這個過程(下面的基本出發點)。

#return dashcontroller hash from more succinct cues 
module DashControl 
    class DashControl 

    attr_accessor :title, :instance, :actions 

    def initialize(title='default title', instance='default instance', actions={}) 
     @title = title 
     @instance = instance 
     initialize_actions(actions) 
    end 

    def initialize_actions(actions) 
     actions.kind_of?(Hash) ? @actions = actions : initialize_tag(actions) 
    end 

    def initialize_tag(tag) 
     case tag 
     when :manage_default 
     @actions = {:statusactions => [], 
        :formactions => [ ['#tabaccount', 'addaccount'], 
             ['#tabuser', 'addusers'], 
             ['#tabadd','adddomain'] ], 
        :linkactions => [ [] ], 
        :filteractions => [ [] ] } 
     when :none 
     @actions = {} 
     #when 
     # @actions = {} 
     else 
     @actions = @actions 
     end 
    end 


    def dashcontroller 
     {:title => @title, :instance => @instance, :actions => @actions } 
    end 

    end 
end 

所以基本上我只需要傳遞的this.dashcontroller一個實例,我也得到我需要在我的控制器少了很多混亂的哈希值。問題是與@instance變量。我想要傳入正在使用的實例@book,@account等,並且它出現爲@book,@account等等。相反,我得到了我在那裏放入的任何內容,如:instance => (contents of that instance)。對我來說這並不像我之前剛剛使用的那樣好。 @account,然後使用它,但看着它可能不會在窗口小部件中產生任何不同,因爲我在處理代碼並處理代碼。

基本上我的問題是如何通過這樣的類來推送實例變量,並且在進入時仍然具有accessibile,而無需在另一側執行任何後向翻轉和變換。可能有更好的方法,但這是我目前正在使用的方法。

編輯:僞代碼

DashControl::DashControl.new("Catchy Title", @book, :none).dashcontroller 
#=> {:title => "Catchy Title", :instance => @book, :actions => {} } 

我想我可以使用它,就像我說的我更多的東西比實際的錯誤或什麼難的是如何認識流動的問題。我不想在實例的另一端做更多的體操,儘管內容在那裏,而這些都是我真正需要的,我只需要一點點的思考就可以減少混亂。我真的需要改進我通過這件事發送的內容,或者使用它來進一步完善我發送的內容是現在要消除的底線課程。

編輯:

我結束了這個折騰,但它是一個學習的經驗......我回去小部件,我知道當我最初設置小部件不止,所以我已經能夠設置它只需要實例變量並引導它所需的內容,而不需要添加其他類,清理我的控制器並將很多事情交回給我懷疑它應該/可能已經啓動的小部件。

+1

你能給你想如何最終出現的僞代碼的例子嗎?比如,你想傳遞給你的函數,你想要結果是什麼? – Veraticus 2012-02-23 23:28:30

回答

0

基於您的代碼和例子,這符合:

# No need to put a class in a namespace of the same name, just make the module a class 
# Also, if you inherit from a struct, it can save you a lot of typing. It defines the setters and getters for you. 
class DashControl < Struct.new(:title, :instance, :actions) 

    # since it looks like you always access it the same way, create a class method 
    # which does this initialization and invocation 
    def self.for(*args) 
    new(*args).dashcontroller 
    end 

    def initialize(title='default title', instance='default instance', actions=:none) 
    # here, we can use our own defaults and normalization and pass the results up to the struct 
    super title, instance, normalize(actions) 
    end 

    # didn't make sense to call this initialize_tag, as it was initializing actions 
    # also there was already an initialize actions method which just checked for the case of a hash 
    # but then elsewhere you checked for other things. Better to just put it all in one method and return it 
    # (then you aren't setting it every time you want to ask it to calculate that value) 
    # also using guard clauses (the if statements that return early) instead of the case, as they are easier to understand 
    def normalize(actions) 
    return Hash.new if actions == :none 
    return actions unless actions == :manage_default 
    default_actions 
    end 

    # the value of default_actions is complicated and noisy, separate it out to its own method 
    # this prevents it from cluttering the code around it, and also allows us to access, 
    # and to do this without the side effects of setting values. 
    def default_actions 
    { :statusactions => [], 
     :formactions => [ ['#tabaccount', 'addaccount'], 
          ['#tabuser', 'addusers'], 
          ['#tabadd','adddomain'] ], 
     :linkactions => [ [] ], 
     :filteractions => [ [] ] } 
    end 

    # use the getters instead of the ivars (I consider this a generally best practice -- and you could have 
    # done it before, since you declared the attr_accessor, even though I'm accessing it through the struct) 
    def dashcontroller 
    {:title => title, :instance => instance, :actions => actions } 
    end 
end 

DashControl.for           # => {:title=>"default title", :instance=>"default instance", :actions=>{}} 
DashControl.for('Catchy Title', '@book', :none)   # => {:title=>"Catchy Title", :instance=>"@book", :actions=>{}} 
DashControl.for('Catchy Title', '@book', :manage_default) # => {:title=>"Catchy Title", :instance=>"@book", :actions=>{:statusactions=>[], :formactions=>[["#tabaccount", "addaccount"], ["#tabuser", "addusers"], ["#tabadd", "adddomain"]], :linkactions=>[[]], :filteractions=>[[]]}} 
DashControl.for('Catchy Title', '@book', a: 'b')   # => {:title=>"Catchy Title", :instance=>"@book", :actions=>{:a=>"b"}} 
DashControl.for('Catchy Title', '@book', 123)    # => {:title=>"Catchy Title", :instance=>"@book", :actions=>123} 
+0

我已閱讀關於OpenStruct,但從未使用它。這提供了更多想法,我可以添加到我正在構建的內容中。 'getters而不是ivars'......我仍然確定如何有效地建立一個班級和管理變量,甚至是什麼是紅寶石的方式,只有我學到的東西迄今爲止工作。我喜歡self.for,這對於做更多的事情很有用,可以少說些我可以使用的東西。謝謝。 – blueblank 2012-02-24 22:42:40

+0

只需重新讀取代碼,該結構是多餘的。我想我很早就開始使用它,但是隨着實現的越來越多,需要引入初始化方法以提供默認值,然後需要將值指定爲super才能對其進行標準化。那時候,我應該切換回attr_accessor。初始化必須調用setter而不是super,但其他代碼沒有改變,因爲它仍然使用getter,所以它不知道它們是否在ivars或任何結構使用中。 – 2012-02-25 10:46:54