像这样的逻辑的最佳 Ruby 习惯用法

发布于 2024-10-17 04:56:11 字数 596 浏览 6 评论 0原文

我在这里概述了两个功能。 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

如何视而不见 2024-10-24 04:56:11

下面是一个常见的 Ruby 习惯用法,用于执行一次昂贵的计算并缓存结果:

def expensive_function
  @expensive_function ||= compute_expensive_function
end

这会导致compute_expense_function 仅被调用一次,无论调用expense_function 多少次。

警告:由于此技术依赖于短路或运算符,因此对于返回 true/false(或 true/falsy)的函数,它无法正常工作。为此,有 promise gem

def initialize
  @expensive_function = promise {compute_expensive_function}
end

def do_something
  ...
  puts @expensive_function
  ...
end

promise gem 比这里介绍的更通用。此外,它还带有一个 future 函数,它可以像 promise 一样缓存结果,而且还在单独的线程中进行计算,这样您就可以抢占先机昂贵的功能:

def initialize
  @expensive_function = future {compute_expensive_function}
end

def do_something
  ...
  puts @expensive_function
  ...
end

Here's a common Ruby idiom for doing an expensive computation once and caching the result:

def expensive_function
  @expensive_function ||= compute_expensive_function
end

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:

def initialize
  @expensive_function = promise {compute_expensive_function}
end

def do_something
  ...
  puts @expensive_function
  ...
end

The promise gem is more versatile than presented here. Also, it comes with a future function, which caches the result like promise, but also does the computation in a separate thread, so that you can get a head-start on the expensive function:

def initialize
  @expensive_function = future {compute_expensive_function}
end

def do_something
  ...
  puts @expensive_function
  ...
end
飘过的浮云 2024-10-24 04:56:11

我不得不说你的版本非常干净和可读,除了你实际上可以删除最后一个 return nil 行,因为默认情况下,如果未指定,ruby 函数将返回 nil 。

或者您也可以为此编写一行:

def test_funct
  @flipped_on && (res = my_funct) && res.length || nil
end

如果返回 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:

def test_funct
  @flipped_on && (res = my_funct) && res.length || nil
end

If returning false is not a problem, the || nil part could also be removed.

Edit: your own version is better :->

帥小哥 2024-10-24 04:56:11

我不太确定 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 中,更常见的是传递(闭包),而不是传递整个方法。事实上,每次使用 mapeach 或其他常见 Ruby 方法时,您都会这样做。

如果您想了解特定任务是如何用 Ruby 进行编码的,您应该说出该任务是什么。你的例子并没有说明这一点。

I am not quite sure what js_funct should do. res in it is completely useless:

def js_funct
  if @flipped_on
    res = my_funct
    if res
      return res.length
    end
  end
  return nil
end

You could just say my_funct.length and get the length of whatever the function my_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 execute my_funct method, and put its result into variable named res.

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 use map, 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文