我在javascript中做了很多次
some_var || some_var = function(){ return "blah"}();
我想知道ruby中的等价物是什么,所以我可以做到
some_var ||= # sequence of operations
修改
Proc.new.call
引起了我的注意,但我也是在某人的代码中遇到过这个问题:
a ||= begin
# do some stuff
# return some stuff
end
这在功能上等同于使用Proc.new.call
??
EDIT2 人们似乎对我想要实现的目标感到困惑。想象一下javascript:
function someExpensiveFunction(){
# do some really expensive stuff
return "some expensive calculations"
}
a || a = someExpensiveFunction();
显然设置a
一次...一次调用昂贵的函数...在这种情况下我不关心范围,我只需要我的返回值是一个计算的事件序列而不是单个值
我很确定我上面a ||= begin; ... end;
的例子是等同的......
答案 0 :(得分:2)
根据你的评论:
不关心范围...只需要一个干净的语法来设置变量使用|| =涉及多行代码
我不确定我理解为什么你觉得你不能使用|| =和lambda。例如,您可以使用
if(some_var.nil?)
# do some stuff
some_var = result_of_doing_some_stuf
end
或者,正如你在你的例子中所说:
a ||= begin
# do some stuff
# return some stuff
end
我不清楚为什么你必须使用proc或lambda。
但是如果你想使用|| =和lambdas,你可以这样做:
calculate = lambda { 1 + 1 }
some_var ||= calculate.call
答案 1 :(得分:1)
s = Proc.new { 5 + 5 }.call
答案 2 :(得分:0)
我一开始不确定你问的是什么部分。逻辑||
确实会影响您的预期操作。在Ruby中,等价物是:
somevar = "blah" unless somevar;
如果somevar为nil值或false值更改为“blah”。如果somevar不是nil或true,则不执行该行。相反的行动是:
somevar = "blah" if somevar;
如果somevar为真或不为零,那将指定“blah”。
Ruby具有与自执行功能类似的语言功能,许多JavaScript库都受到这些功能的启发。
查看此页面以获取更多信息:
http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html
这里有关于“块和迭代器”的部分。此外,“交易块”和“块可以关闭”。
基本上Ruby块和ruby lambda是最接近Javascript自执行功能的东西。
答案 3 :(得分:0)
你可以用lambda块
来做some_var ||= lambda { "something" }.call
或
some_var ||= Proc.new { "something" }.call
在JS中,自执行函数通常用于避免污染范围,因此您可以在内部使用局部变量,但不要公开它们。不幸的是,如果在1.9之前的Ruby中使用块,则情况并非如此,其中块没有自己的范围。
# Ruby 1.8.7
x = "some initial value"
some_var ||= Proc.new { x = 10; x + 2 }.call #=> 12
x #=> 10
所以,如果是这样的话,那么你可能会尝试做更好的解决方案。 Ruby不是Javascript 。}
编辑:抱歉,我忘记了范围与变量赋值中的变量定义。更新了代码段以反映答案 4 :(得分:0)
你可以这样做:
def run
@a ||= begin
x = 1 + 1
puts "Calculated x"
x
end
end
puts "run = #{run}" # => Calculated x, run = 2
puts "run = #{run}" # => run = 2
如果要传递变量
,请使用lambdadef run
@a ||= lambda do |i|
x = i + i
puts "Calculated x"
x
end.call(1)
end
puts "run = #{run}" # => Calculated x, run = 2
puts "run = #{run}" # => run = 2
但如果你要立即调用lambda,那么使用方法会不那么神奇和可读性
def calc(i)
x = i + i
puts "Calculated x"
x
end
def run
@a ||= calc(1)
end
puts "run = #{run}" # => Calculated x, run = 2
puts "run = #{run}" # => run = 2
答案 5 :(得分:0)
块(开始...结束)proc和lambda之间的区别是句柄返回的方式。块中不允许返回。从它定义的位置返回Proc返回并在Lambda中返回做预期的
所以
def f()
a = Proc.new do
return 5 # exit from f
end.call
# never called
a+10
end
返回5(而不是15)
def g()
a = lambda do
return 5
end.call
a+10
end
返回15(正如预期的那样)
和
def f()
a = begin
return 5
end
a+10
end
无法编译。
如果您没有在块中使用return,那么您可以使用begin ... do(顺便说一句,我喜欢它)。