2013-06-19 198 views
4

我正在编写一些代码,它最终变得太丑了,我不喜欢。无论如何,我可以重构它,以便我不使用嵌套if语句?Ruby:嵌套if语句

def hours_occupied(date) 
    #assuming date is a valid date object  
    availability = get_work_hours(date) 
    focus = "work" 

    if availability.nil 
    availability = get_family_hours(date) 
    focus = "family" 

    if availability.nil 
     availability = get_friend_hours(date) 
     focus = "friends" 
    end 
    end 
end 

我知道我能够为可用性

availability = get_work_hours(date) || get_family_hours(date) || get_friend_hours(date) 

做这样的事情,但我怎么设置相应的重点变量?

+3

我们可以假设您没有显示完整的方法吗?否则分配那些未使用的变量是没有意义的。如果是这种情况,请在方法底部添加“...”作为占位符。 – tokland

+1

@tokland:我发现自己完全无法理解他的代码的主题和目的,这使我无法回应。 –

回答

1

还有一个办法就是,如果有必要重新分配值:

def hours_occupied(date) 
    availability, focus = get_work_hours(date), "work" 
    availability, focus = get_family_hours(date), "family" unless availability 
    availability, focus = get_friend_hours(date), "friend" unless availability 
end 

或使用迭代器:

def hours_occupied(date) 
    availability = focus = nil 
    %w(work family friend).each {|type| availability, focus = self.send(:"get_#{type}_hours", date), type unless availability} 
end 
5

,因为它清楚地表明,每一种情况下是相互排斥的,我会做类似如下:

def hours_occupied(date) 
    if availability = get_work_hours(date) 
    focus = "work" 
    elsif availability = get_family_hours(date) 
    focus = "family" 
    elsif availability = get_friend_hours(date) 
    focus = "friends" 
    end 
end 
+2

Ruby条件是表达式,所以不需要重复'focus' 3次 – tokland

3

我会写:

def hours_occupied(date) 
    focus = if (availability = get_work_hours(date)) 
    "work" 
    elsif (availability = get_family_hours(date)) 
    "family" 
    elsif (availability = get_friend_hours(date)) 
    "friends" 
    end 
    # I guess there is more code here that uses availability and focus. 
end 

但是,我不知道有不同不同类型的方法是一个好主意,它使代码更难写。一种不同的方法使用Enumerable#map_detect

focus, availability = [:work, :family, :friends].map_detect do |type| 
    availability = get_hours(date, type) 
    availability ? [type, availability] : nil 
end 
+0

我不喜欢在条件测试中看到任务。它太像C或Perl,给我做恶梦。非常感谢。 :-) –

+0

@theTinMan:不客气:-)有些人会说,如果语言允许它(例如Python不),为什么要避免它?你不能告诉== = a =?但我不会:-)我喜欢这种构造,因为它简化了嵌套表达式较少的代码。请注意,parens使其更加醒目。 – tokland

1

一个情况下也是一种选择:

focus = case availability 
when get_work_hours(date) 
    "work" 
when get_family_hours(date) 
    "family" 
when get_friend_hours(date) 
    "friends" 
end 
+0

要么这是错误的或'case'工作不同于我想:-) – tokland

+0

@Tokland虚拟数据示例[此处](http://ideone.com/70t9oY) – steenslag

+1

但“可用性”必须保持第一个非零方法调用的* result *,事先不知道。 – tokland