如果未将函数返回的值存储在变量中,是否可以获取该值?

时间:2019-11-19 15:44:05

标签: ruby

我正在调试看起来像这样的方法

def method
  if something
   "a"
  elsif somethingelse
   "b"
  #elseif ...
  else
   "z"
  end
  # the current return value is ???
end

ruby​​的工作方式给人的印象是,每个表达式都返回一个值 ,并将其保存在某个位置。最后一个将在方法末尾返回(如果未找到return)。

在上述情况下,if条件返回一个字符串(存储在某个地方?),在方法的末尾,由于没有其他更改,因此将返回该字符串。

是否可以访问该值? (类似于控制台中的_,它会返回上一条命令的结果)

1 个答案:

答案 0 :(得分:2)

[基于Aleksei Matiushkin's comment]


在Ruby中,控件表达式具有返回值。

您的方法仅返回if expression的结果。您可以通过tap进行检查:

javax.management.openmbean.CompositeType(
    name=java.lang.management.MemoryUsage,
    items=(
            (itemName=committed,itemType=javax.management.openmbean.SimpleType(name=java.lang.Long)),
            (itemName=init,itemType=javax.management.openmbean.SimpleType(name=java.lang.Long)),
            (itemName=max,itemType=javax.management.openmbean.SimpleType(name=java.lang.Long)),
            (itemName=used,itemType=javax.management.openmbean.SimpleType(name=java.lang.Long))
        )
    )

如果您遇到更复杂的情况而没有最后一个表达式,例如:

def foo(b)
  if b
    123
  else
    456
  end.tap { |result| p result: result }
end

foo(true)
# prints {:result=>123}
#=> 123

foo(false)
# prints {:result=>456}
#=> 456

您可以使用优化方法来替换方法:

class C
  def foo(b)
    return 123 if b
    456
  end
end

用法:

module M
  refine C do
    def foo(*)
      super.tap { |result| p result: result }
    end
  end
end

另一种方法是使用TracePoint来执行:

using M

c = C.new

c.foo(true)
# prints {:result=>123}
#=> 123

c.foo(false)
# prints {:result=>456}
#=> 456

输出:

def foo(b)             # 1
  return 123 if b      # 2
  456                  # 3
end                    # 4

TracePoint.trace(:return) do |tp|
  puts "method `#{tp.method_id}' returned #{tp.return_value.inspect} on line ##{tp.lineno}"
end

foo(true)
foo(false)

请注意,这将打印所有方法调用的返回值。您可能希望将其限制为method `foo' returned 123 on line #2 method `foo' returned 456 on line #4