Ruby等价于javascript自动执行函数
我经常在javascript中这样做Ruby等价于javascript自动执行函数,javascript,ruby,Javascript,Ruby,我经常在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 这在功能上是否等同于使用P
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。。。结束代码>相当于 一开始我不确定你在问什么。逻辑| |
确实会影响预期的操作。在Ruby中,等价物是:
s = Proc.new { 5 + 5 }.call
somevar = "blah" unless somevar;
如果somevar为nil值或false值,则将其更改为“blah”。如果somevar不是nil或true,则不执行该行。相反的行动是:
somevar = "blah" if somevar;
如果somevar为true或非nil,则将赋值为“blah”
Ruby具有类似于自执行函数的语言特性,许多javascript库都受到这些特性的启发
有关更多信息,请查看此页面:
关于“块和迭代器”的部分在这里很有意思。还有“事务块”和“块可以是闭包”
从本质上讲,Ruby块和Ruby lambda是最接近Javascript自动执行功能的东西。您可以使用lambda块来实现它
some_var ||= lambda { "something" }.call
或
在JS中,自执行函数通常用于避免污染作用域,因此您可以在内部使用局部变量,但不要公开它们。不幸的是,如果在Ruby 1.9之前的版本中使用块,情况并非如此,块没有自己的作用域
# Ruby 1.8.7
x = "some initial value"
some_var ||= Proc.new { x = 10; x + 2 }.call #=> 12
x #=> 10
因此,如果是这样的话,可能有一个更好的解决方案来解决你的问题。Ruby不是Javascript
对不起,我忘记了作用域和变量赋值中的变量定义。根据您的评论更新了代码段以反映这一点:
不关心范围界定。。。只需要使用包含多行代码的| |=设置变量的干净语法
我不知道我是否理解你为什么觉得你没有使用| |和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
你可以做:
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
如果要传递变量,请使用lambda
def 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
块(开始…结束)proc和lambda之间的区别在于句柄返回的方式。块中不允许返回。在Proc中返回从定义它的位置返回,在Lambda中返回,执行预期的操作
所以
返回5(而不是15)
返回15(如预期)
及
不编译
如果在块中未使用return,则可以使用begin。。。do(顺便说一句,我喜欢)。我了解| | |做什么,我想| | |做一些| | | | | | | | | | | |做一些|现在看到你的。您已经接受了答案,所以我不会尝试编辑此答案。我刚刚遇到:a | | |=begin#一些代码结尾
您见过吗?它是等效的吗?一个糟糕的格式没有正确出现,我将编辑我的postRuby 1.8.6,在上面的块作用域示例中给出未定义的x。我所做的或读到的关于ruby的所有事情都表明它必须始终支持块作用域。请参阅我的更新答案,关于块范围,您是对的。我想知道OP试图用这种编程风格做什么。我仍然很困惑——上面的snipper中没有变量阴影。事实上,您正在演示相反的情况。例如,在JS中,您可以通过在内部/匿名函数中使用var声明一个名称相同但作用域不同的变量。如果不使用var标记它,它将通过闭包假定外部作用域的标识。在Ruby中,您永远不会像在JS中那样“声明”变量。内部块捕获闭包中的外部变量。如果它是阴影,结果将是“一些初始值”,但它不是-结果是10,表明没有阴影,只是一个闭包。好吧,我的观点是,在Ruby中,你不能在块作用域中声明局部变量。与…比较不管怎样,我刚刚看到了OP想要做什么,这样我们就可以把讨论转移到聊天室了?你到底想做什么?Ruby具有块级范围,这与JavaScript具有的词法范围不同。通常你会在JS中看到匿名函数来避免作用域问题。。。我只是想要一个干净的语法来使用| |=设置一个变量,它涉及多行代码。我实际上是在试图避免Proc/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
def f()
a = Proc.new do
return 5 # exit from f
end.call
# never called
a+10
end
def g()
a = lambda do
return 5
end.call
a+10
end
def f()
a = begin
return 5
end
a+10
end