2017-10-04 37 views
1

我下面舉個例子Ruby代碼:紅寶石儘量不要處理異常

def example_method(obj) 
    ExampleClass.new(color1: @theme.try(obj['color1'].to_sym)) 
end 

哪些應該通過其中的obj['color1']作爲一個符號或零到類。

但是,如果color1未通過,則會收到錯誤:NoMethodError: undefined method 'to_sym' for nil:NilClass

不應該try方法處理異常嗎?


更新:根據意見......我解決它做三元:

ExampleClass.new(color1: obj['color1'].present? ? @brand_theme.try(obj['color1'].try(:to_sym)) : nil) 

回答

2

try被稱爲@theme對象。由於obj['color1']返回nil,所以拋出nil錯誤,然後在nil上調用to_sym

你不得不改變代碼

ExampleClass.new(color1: @theme.try(obj['color1'].try(:to_sym) || '')) 

接住。然後你將不得不美化代碼。

如何美化工作將取決於用例,所以我只能提供一些通用的指針。一種方法是有一個默認值avoid having to deal with the null object

而不是繞過零,一個簡單的返回默認值:

color_key = obj.fetch('color') { 'default_color' }.to_sym 
ExampleClass.new(color1: @theme.send(color_key))) 

這使得利用它能使返回默認值fetch method的。這樣你將永遠有一個定義的值。

+0

給我錯誤'TypeError:nil不是符號也不是字符串' – Cameron

+0

在這個例子中'obj ['color1']'將是零。所以我們會通過零的嘗試。 – Cameron

+0

那麼當我提到的obj是零時,我該如何處理呢?但如果存在的話,我想把它作爲傳遞給課堂的主題上的符號。 – Cameron

2

從評論:

In this example obj['color1'] would be nil. So we'd be passing nil to the try.

是的,這是一個錯誤。你不能調用沒有名字的方法。 技術上,你可以通過做.try(obj['color'].to_s)來避免這個錯誤,但它是錯誤的。

我會明確檢查是否存在,如果它不在那裏,請儘早保釋。如果參數爲nil,即obj['color1']

def theme_color(name) 
    return unless name 
    return unless @theme.respond_to?(name) 
    @theme.public_send(name) 
end 

def example_method(obj) 
    ExampleClass.new(color1: theme_color(obj['color1'])) 
end 

theme_color回報nil

def example_method(obj) 
    return unless obj['color1'].present? 

    ExampleClass.new(color1: @theme.try(obj['color1'])) 
end 
+0

我不能保釋。我們通過多種顏色。有些是存在的,有些不是我們爲什麼首先嚐試的原因。 – Cameron

+0

我已經通過做三元固定(見更新OP)。 – Cameron

+0

@Cameron:是的,當你要返回一個example_class的時候確實比較好。該代碼可以被美化,但它應該工作。 –

3

你可以寫一個輔助方法。如果theme不響應給定的方法,它也返回nil。否則,它會調用name指定的方法。

請注意,respond_to?public_send接受字符串或符號,因此不需要to_sym

你也可以定義輔助方法,爲您的@theme類的實例方法:

class Theme 
    def color(name) 
    return unless name 
    return unless respond_to?(name) 
    public_send(name) 
    end 

    def red 
    'FF0000' 
    end 
end 

@theme = Theme.new 
@theme.red   #=> "FF0000" 
@theme.color(:red) #=> "FF0000" 
@theme.color('red') #=> "FF0000" 
@theme.color('green') #=> nil 
@theme.color(nil)  #=> nil 

,並通過調用它:

def example_method(obj) 
    ExampleClass.new(color1: @theme.color(obj['color1'])) 
end 

請記住,這些方法(使用public_sendtry )允許你在你的@theme對象上調用任意方法。將顏色保存在散列中可能更安全。