像这样的逻辑的最佳 Ruby 习惯用法
我在这里概述了两个功能。 js_funct 是一种常见的 js 样式,而 test_funct 是我对其进行 Ruby 化的尝试。
有更好的/替代的/更干净的/红宝石式的方法来处理这个问题吗?
@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
I've outlined two functions here. The js_funct is a common js style and test_funct is my attempt to kind of Ruby-ize it.
Any better/alternative/cleaner/ruby-ish ways of handling this?
@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
EDIT:
Think I might have answered my own question here. Requires a lot of thinking to interpret this though.
def test_funct
res = my_funct and res.length if @flipped_on
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
下面是一个常见的 Ruby 习惯用法,用于执行一次昂贵的计算并缓存结果:
这会导致compute_expense_function 仅被调用一次,无论调用expense_function 多少次。
警告:由于此技术依赖于短路或运算符,因此对于返回 true/false(或 true/falsy)的函数,它无法正常工作。为此,有 promise gem:
promise gem 比这里介绍的更通用。此外,它还带有一个
future
函数,它可以像promise
一样缓存结果,而且还在单独的线程中进行计算,这样您就可以抢占先机昂贵的功能:Here's a common Ruby idiom for doing an expensive computation once and caching the result:
This causes compute_expensive_function to be called only once, no matter how many times expensive_function is called.
Caveat: Because this technique relies upon the short-circuit or operator, it won't work correctly for functions that return true/false (or truthy/falsy). For that, there is the promise gem:
The promise gem is more versatile than presented here. Also, it comes with a
future
function, which caches the result likepromise
, but also does the computation in a separate thread, so that you can get a head-start on the expensive function:我不得不说你的版本非常干净和可读,除了你实际上可以删除最后一个 return nil 行,因为默认情况下,如果未指定,ruby 函数将返回 nil 。
或者您也可以为此编写一行:
如果返回 false 不是问题,则 || nil 部分也可以被删除。
编辑:你自己的版本更好:->
I have to say your version is quite clean and readable, except you can in fact remove the last return nil line, since by default a ruby function returns nil if not specified.
Or you could also write a single line for this:
If returning false is not a problem, the || nil part could also be removed.
Edit: your own version is better :->
我不太确定 js_funct 应该做什么。其中的
res
完全没用:您只需输入
my_funct.length
即可获取函数my_funct
返回的长度。但似乎下面的事情让你感到困惑:在 Ruby 中,函数(我们称它们为方法,因为它们总是属于一个对象)不是第一类对象。因此,您不能说
res = my_funct
,希望将函数分配给变量,就像在 JavaScript 中那样。在 Ruby 中,该行将首先执行my_funct
方法,并将其结果放入名为res
的变量中。例如,如果您想检查是否定义了方法,可以使用
Object#respond_to?
方法。如果您想将方法包装到对象中以便传递它,则应该使用
Object#method
方法。但在 Ruby 中,更常见的是传递块(闭包),而不是传递整个方法。事实上,每次使用map
、each
或其他常见 Ruby 方法时,您都会这样做。如果您想了解特定任务是如何用 Ruby 进行编码的,您应该说出该任务是什么。你的例子并没有说明这一点。
I am not quite sure what
js_funct
should do.res
in it is completely useless:You could just say
my_funct.length
and get the length of whatever the functionmy_funct
returns.But it seems that following thing confuses you: in Ruby, functions (we call them methods, as they always belong to an object) are not first-class objects. So you can't say
res = my_funct
, hoping that you would assign a function to a variable, as you would in JavaScript. In Ruby, that line would first executemy_funct
method, and put its result into variable namedres
.If you would like to check if a method is defined, you can, for example, use
Object#respond_to?
method.If you would like to wrap your method into an object in order to pass it around, you should use
Object#method
method. But in Ruby it's more common to pass blocks (closures) around, rather than whole methods. You are in fact doing that every time you usemap
,each
or other common Ruby methods.If you would want to see how a particular task is coded in Ruby, you should say what the task is. Your example doesn't tell that.