2017-08-05 46 views
0

參數我想要定義的方法具有以下特徵:可選性的依賴於其它參數

  • 一個。需要name
  • b。 all_day是可選的。
  • c。需要start_time
  • d。除非all_daytrue,否則需要end_time
  • e。 location是可選的,是一個看起來像哈希:需要

    location = {name => "Chelsea Piers", address => "10th Avenue", city => "New York"} 
    

    爲此location[:name],以及其它按鍵是可選的。

這是我的代碼:

class Event 
    def initialize(name, all_day=false, start_time, end_time, **location) 
    @name = name 
    @all_day = all_day 
    @start_time = Time.parse(start_time) 
    @end_time = Time.parse(end_time) 
    @location = location 
    end 
end 

如何實現需求d。?如果all_daytrue,我沒有location,是在下面的代碼的語法爲參數:

Event.new(name, true, start_time, location) 

是否正確?我可以創建一個新Event對象是這樣的:

Event.new(name, false, start_time, end_time) 
+5

你有沒有考慮將所有可選的東西移動到命名參數?你最終會手動驗證參數並提出自己的'ArgumentError',但所有內容都不會令人困惑,並且更易於閱讀。我發現,如果有更多的位置參數比其中幾個位置變得更難看,那麼當你開始拋出可選參數時就會加倍。 –

+1

不知道命名參數。非常感謝你的信息! –

回答

4

旁註:

location = {name => "Chelsea Piers", 
      address => "10th Avenue", 
      city => "New York"} 

不是有效的Ruby對象。這可能是兩種:

location = {name: "Chelsea Piers", 
      address: "10th Avenue", 
      city: "New York"} 

或:

location = {:name => "Chelsea Piers", 
      :address => "10th Avenue", 
      :city => "New York"} 

旁註#2:

有一個XY的問題:你其實並不需要all_day參數都沒有。它可以來自是否設置end_time


最後,命名參數和雙參數圖示可能location混合。總結:

class Event 
    def initialize(name, start_time, end_time = nil, location_name:, **location) 
    @name = name 
    @all_day = !end_time.nil? 
    @start_time = Time.parse(start_time) 
    @end_time = Time.parse(end_time) if end_time 
    @location = location.merge(name: location_name) 
    end 
end 
+0

這個問題說'location'是可選的,但是'location [:name]'是必需的,這是無條件無意義的(你不能沒有前者)。所以我解釋說,OP意味着後者是強制性**,以防給予前者**。 – sawa

+1

@sawa那麼它可以通過內部檢查來實現''location.empty? ||位置[:名稱]'只;如果這是真的,則OP可能簡單地忽略此答案的'location_name'參數部分。 – mudasobwa

+0

謝謝你的幫助!那麼可以在這種情況下使用關鍵字參數的位置參數嗎? –