ruby方法返回值的最佳实践

时间:2023-01-05 21:17:56

I find myself doing the following a lot to define return values from ruby methods:

我发现自己要做很多事情来定义ruby方法的返回值:

def foo
  val = (some expression)
  val
end

This always seems a bit contrived. What's the best practice here?

这似乎有点做作。这里的最佳做法是什么?

6 个解决方案

#1


11  

It is unnecessary to save it to a variable unless (some expression) is heavy and will be called multiple times. In that case you might want to cache it.

除非(某些表达式)很重并且将被多次调用,否则不必将其保存到变量中。在这种情况下,您可能希望缓存它。

I would go with either:

我会选择:

def foo
  (some expression)
end

or for caching:

或用于缓存:

def foo
  @val ||= (some expression)
end

#2


9  

Note that as of Ruby 1.9 you can use Object#tap to save a value for the return at the end if you need to do something else with the value before returning it:

请注意,从Ruby 1.9开始,如果在返回之前需要对值执行其他操作,则可以使用Object#tap为最后的返回值保存值:

def foo
  (some expression).tap do |val|
    # use val here
  end
  # The return value of the tap is _val_
  # and hence the return value of your method
end

#3


1  

As long as your last expression evaluates to the desired one you want to return, you're safe.

只要您的最后一个表达式评估为您想要返回的所需表达式,您就是安全的。

def foo
  val = (some expression)
end

is identical to the one in the question as it evaluates to (some expression), just like val would.

与问题中的那个相同,因为它评估为(某些表达式),就像val一样。

#4


1  

I personally like using return to explicitly call out what is being returned. It's extra code that Ruby doesn't require you to use, but it helps me with readability. It also allows you to have multiple exit points in your method since execution of your method will stop as soon as return is called.

我个人喜欢使用return来明确地调出返回的内容。这是Ruby不需要你使用的额外代码,但它有助于我提高可读性。它还允许您在方法中有多个退出点,因为一旦调用return,方法的执行就会停止。

This really isn't much different from the example you gave in your original question.

这与您在原始问题中给出的示例没有太大区别。

def foo
  val = (some expression)
  val
end

could look like

可能看起来像

def foo
  return (some expression)
end

#5


1  

Temporary variables are evil because they increase connascence.

临时变量是邪恶的,因为它们增加了灵感。

http://www.mgroves.com/what-is-connascence

http://www.mgroves.com/what-is-connascence

ReplaceTempWithQuery is a refactoring I use a lot:

ReplaceTempWithQuery是我经常使用的重构:

def discount_price
  base_price = quantity * item_price
  if (base_price > 1000)
    base_price * 0.95
  else
    base_price * 0.98
  end
end

Code after refactoring:

重构后的代码:

def discount_price
  if (base_price > 1000)
    base_price * 0.98
  else
    base_price * 0.98
  end
end

def base_price
  quantity * item_price
end

http://www.refactoring.com/catalog/replaceTempWithQuery.html

http://www.refactoring.com/catalog/replaceTempWithQuery.html

#6


1  

I sometimes do what you have in your question.

我有时会在你的问题中做你所拥有的。

Some cases where I do it are:

我做的一些情况是:

  1. When I'm doing imperitive programming (foo = Foo.new; foo.modify_state; foo)
  2. 当我做不完整的编程时(foo = Foo.new; foo.modify_state; foo)
  3. If I want to validate an object before returning, but as Phrogz mentioned, Object#tap may help here (foo = new_foo; raise if foo.empty?; foo)
  4. 如果我想在返回之前验证对象,但正如Phrogz所提到的,Object#tap可能在这里有所帮助(foo = new_foo;如果foo.empty?; foo则提高)
  5. When I want to make it clear that I'm returning a variable, rather than doing more stuff (do_this; do_that; do_other_thing; result #done!)
  6. 当我想清楚地表明我正在返回变量时,而不是做更多的事情(do_this; do_that; do_other_thing;结果#done!)

It may indicate code smells though, such as in case 1.

它可能表示代码有异味,例如在案例1中。

#1


11  

It is unnecessary to save it to a variable unless (some expression) is heavy and will be called multiple times. In that case you might want to cache it.

除非(某些表达式)很重并且将被多次调用,否则不必将其保存到变量中。在这种情况下,您可能希望缓存它。

I would go with either:

我会选择:

def foo
  (some expression)
end

or for caching:

或用于缓存:

def foo
  @val ||= (some expression)
end

#2


9  

Note that as of Ruby 1.9 you can use Object#tap to save a value for the return at the end if you need to do something else with the value before returning it:

请注意,从Ruby 1.9开始,如果在返回之前需要对值执行其他操作,则可以使用Object#tap为最后的返回值保存值:

def foo
  (some expression).tap do |val|
    # use val here
  end
  # The return value of the tap is _val_
  # and hence the return value of your method
end

#3


1  

As long as your last expression evaluates to the desired one you want to return, you're safe.

只要您的最后一个表达式评估为您想要返回的所需表达式,您就是安全的。

def foo
  val = (some expression)
end

is identical to the one in the question as it evaluates to (some expression), just like val would.

与问题中的那个相同,因为它评估为(某些表达式),就像val一样。

#4


1  

I personally like using return to explicitly call out what is being returned. It's extra code that Ruby doesn't require you to use, but it helps me with readability. It also allows you to have multiple exit points in your method since execution of your method will stop as soon as return is called.

我个人喜欢使用return来明确地调出返回的内容。这是Ruby不需要你使用的额外代码,但它有助于我提高可读性。它还允许您在方法中有多个退出点,因为一旦调用return,方法的执行就会停止。

This really isn't much different from the example you gave in your original question.

这与您在原始问题中给出的示例没有太大区别。

def foo
  val = (some expression)
  val
end

could look like

可能看起来像

def foo
  return (some expression)
end

#5


1  

Temporary variables are evil because they increase connascence.

临时变量是邪恶的,因为它们增加了灵感。

http://www.mgroves.com/what-is-connascence

http://www.mgroves.com/what-is-connascence

ReplaceTempWithQuery is a refactoring I use a lot:

ReplaceTempWithQuery是我经常使用的重构:

def discount_price
  base_price = quantity * item_price
  if (base_price > 1000)
    base_price * 0.95
  else
    base_price * 0.98
  end
end

Code after refactoring:

重构后的代码:

def discount_price
  if (base_price > 1000)
    base_price * 0.98
  else
    base_price * 0.98
  end
end

def base_price
  quantity * item_price
end

http://www.refactoring.com/catalog/replaceTempWithQuery.html

http://www.refactoring.com/catalog/replaceTempWithQuery.html

#6


1  

I sometimes do what you have in your question.

我有时会在你的问题中做你所拥有的。

Some cases where I do it are:

我做的一些情况是:

  1. When I'm doing imperitive programming (foo = Foo.new; foo.modify_state; foo)
  2. 当我做不完整的编程时(foo = Foo.new; foo.modify_state; foo)
  3. If I want to validate an object before returning, but as Phrogz mentioned, Object#tap may help here (foo = new_foo; raise if foo.empty?; foo)
  4. 如果我想在返回之前验证对象,但正如Phrogz所提到的,Object#tap可能在这里有所帮助(foo = new_foo;如果foo.empty?; foo则提高)
  5. When I want to make it clear that I'm returning a variable, rather than doing more stuff (do_this; do_that; do_other_thing; result #done!)
  6. 当我想清楚地表明我正在返回变量时,而不是做更多的事情(do_this; do_that; do_other_thing;结果#done!)

It may indicate code smells though, such as in case 1.

它可能表示代码有异味,例如在案例1中。