代码之家  ›  专栏  ›  技术社区  ›  brad

Ruby等价于javascript的自执行函数

  •  5
  • brad  · 技术社区  · 14 年前

    我经常使用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
    

    这在功能上等同于使用 进程新调用 ??

    编辑2 人们似乎对我要达到的目标感到困惑。用javascript想象一下:

    function someExpensiveFunction(){
      # do some really expensive stuff
      return "some expensive calculations"
    }
    
    a || a = someExpensiveFunction();
    

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

    我很确定我上面的例子 a ||= begin; ... end; 相当于。。。

    6 回复  |  直到 14 年前
        1
  •  2
  •   Matt    14 年前

    根据您的评论:

    不在乎范围。。。只需要一个干净的语法来使用包含多行代码的| |=设置变量

    我不知道为什么你觉得你没有用兰姆达。例如,你可以使用

    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
    
        2
  •  1
  •   ceth    14 年前
    s = Proc.new { 5 + 5 }.call
    
        3
  •  0
  •   Berin Loritsch    14 年前

    一开始我不知道你在问什么。合乎逻辑的 || 会影响您的预期操作。在Ruby中,等价物是:

    somevar = "blah" unless somevar;
    

    如果somevar为nil值或false值,则更改为“blah”。如果somevar不是nil或true,则不执行该行。相反的做法是:

    somevar = "blah" if somevar;
    

    如果某个变量为真或不为零,则该变量将被赋值为“blah”。

    Ruby具有类似于自执行函数的语言特性,许多javascript库都受到了这些特性的启发。

    查看此页了解更多信息:

    http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html

    关于“块和迭代器”的部分在这里会很有趣。此外,“用于事务的块”和“块可以是闭包”。

    基本上,Ruby块和Ruby lambda是最接近Javascript的自执行函数的东西。

        4
  •  0
  •   Chubas    14 年前

    你可以用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 .}

    编辑:抱歉,我忘记了作用域中的变量定义和变量赋值。更新了代码片段以反映

        5
  •  0
  •   Petrik de Heus    14 年前

    你可以:

    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
    
        6
  •  0
  •   mb14    14 年前

    一个街区之间的区别(开始。。。结束)proc和lambda是句柄返回的方式。块中不允许返回。Proc中的Return从定义它的位置返回,Lambda中的Return执行预期的操作

    所以

    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。。。是的(顺便说一句我喜欢)。