我在这里概述了两个功能。 js_funct是一种常见的js样式,test_funct是我尝试Ruby-ize它。
任何更好/替代/清洁/红宝石的处理方式?
@flipped_on = true
# assume my_funct is expensive
def my_funct
'success'
end
def test_funct
res = my_funct if @flipped_on
res.length if res
end
def js_funct
if @flipped_on
res = my_funct
if res
return res.length
end
end
return nil
end
p test_funct
p js_funct
编辑:
想想我可能在这里回答了我自己的问题。虽然需要很多思考才能解释这一点。
def test_funct
res = my_funct and res.length if @flipped_on
end
答案 0 :(得分:2)
这是一个常见的Ruby习惯用法,用于执行一次昂贵的计算并缓存结果:
def expensive_function
@expensive_function ||= compute_expensive_function
end
这会导致compute_expensive_function只被调用一次,无论burn_function被调用多少次。
警告:因为这种技术依赖于短路或操作符,所以对于返回true / false(或truthy / falsy)的函数它将无法正常工作。为此,有promise gem:
def initialize
@expensive_function = promise {compute_expensive_function}
end
def do_something
...
puts @expensive_function
...
end
承诺宝石比这里介绍的更通用。此外,它还附带一个future
函数,它将结果缓存为promise
,但也可以在单独的线程中进行计算,这样您就可以在昂贵的函数上获得先机:
def initialize
@expensive_function = future {compute_expensive_function}
end
def do_something
...
puts @expensive_function
...
end
答案 1 :(得分:0)
我必须说你的版本非常干净和可读,除了你实际上可以移除最后的返回nil 行,因为默认情况下,如果没有指定,ruby函数返回nil。
或者您也可以为此写一行:
def test_funct @flipped_on && (res = my_funct) && res.length || nil end
如果返回false不是问题, ||零部分也可以删除。
编辑:您自己的版本更好: - >
答案 2 :(得分:0)
我不太确定js_funct
应该做什么。其中res
完全没用:
def js_funct
if @flipped_on
res = my_funct
if res
return res.length
end
end
return nil
end
您可以说my_funct.length
并获取函数my_funct
返回的长度。
但似乎下面的事情让你感到困惑:在Ruby中,函数(我们称之为方法,因为它们总是属于一个对象)不是第一类对象。因此,您不能说res = my_funct
,希望您将函数分配给变量,就像在JavaScript中一样。在Ruby中,该行首先执行 my_funct
方法,并将其结果放入名为res
的变量中。
如果您想检查方法是否已定义,您可以使用Object#respond_to?
方法。
如果您希望将方法包装到对象中以便传递它,则应使用Object#method
方法。但是在Ruby中,传递 blocks (闭包)更常见,而不是整个方法。事实上,每次使用map
,each
或其他常见的Ruby方法时,您都会这样做。
如果您想了解如何在Ruby中编写特定任务,您应该说明该任务是什么。你的例子没有说明。