Ruby相当于一个javascript自执行功能

时间:2010-11-24 15:06:57

标签: 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

这在功能上等同于使用Proc.new.call ??

EDIT2 人们似乎对我想要实现的目标感到困惑。想象一下javascript:

function someExpensiveFunction(){
  # do some really expensive stuff
  return "some expensive calculations"
}

a || a = someExpensiveFunction();

显然设置a一次...一次调用昂贵的函数...在这种情况下我不关心范围,我只需要我的返回值是一个计算的事件序列而不是单个值

我很确定我上面a ||= begin; ... end;的例子是等同的......

6 个答案:

答案 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

如果要传递变量

,请使用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

答案 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(顺便说一句,我喜欢它)。