• Ruby 中的闭包-代码块


    看了一片文章https://ruby-china.org/topics/38385讲closure的。

    写下一些感想:

    闭包就是 一个函数能够记住和存取它的lexical作用域,即使这个函数是在它的lexical作用域的外面执行。

    当一个函数被写出来时,这个函数的closure就已经确定了。

    javascript中有闭包的概念:https://www.cnblogs.com/chentianwei/p/9739714.html

    Ruby中的关键字定义def是没有闭包的。它创建一个封闭的作用域。

    但是Ruby有闭包的概念这就是--代码块。

    a = 100
    
    define_method :add_a do
      a = a + 1
    end
    
    puts add_a # => 101
    puts add_a # => 102
    puts add_a # => 103

     这个例子使用了define_method方法搭配一个代码块来定义方法。我们就可以访问外部的作用域的局部变量a。

    Ruby就是使用代码块来表示闭包的。 

     可以参考《Ruby元编程》相关章节的例子:

    def my_method
      x = "GoodBye"
      puts yield("cruel")
    end
    
    x = "Hello"
    my_method  do |y|
      "#{x}, #{y} world!"
    end

    代码块绑定了变量x。即外部作用域的变量跟着代码块一起走!

    代码块的意义:

    在Ruby的开源世界,代码块无处不在:

    1.容错涉及:

    Ruby承袭于Lisp,代码块的运行会自动返回最后一条语句或者表达式的值,于是有些库也考虑到了用代码块来进行容错处理。

    例子:

    > hash = {}
    > value = hash.fetch('a') { 'default value' }
     => "default value"

    因为hash是空的,没有"a", 所以会返回代码块中的字符串,如果不提供代码块,就会报错❌。

    2. DSL

    3. 蹩脚的函数

    代码块可以看作是一个蹩脚的函数,虽然一般情况下可以作为某个方法的回调,但在Ruby中代码块需要依赖其他机制来存在,而不是JS中的函数那样独立存在。

    当使用代码块来定义一个匿名函数时,需要搭配lambda关键字或Proc类来实现。

    > c = lambda() {}
     => #<Proc:0x00007ff47b8546a8@(irb):6 (lambda)>
    > c.class
     => Proc
    
    > (lambda() { 'hello' }).call
     => "hello"
    > (lambda() { 'hello' })[]
     => "hello"
    > (Proc.new { 'hello' }).call
     => "hello"
    > (Proc.new { 'hello' })[]
     => "hello"

    x = "tom"
    (lambda() {"Hello,#{x}"}).call 

    以上都是常用的定义匿名函数的方式,本质上它们都是Proc类的实例,需要显式地利用Proc#call方法或者语法糖[]来调用它们。

    总结:

    这篇文章介绍了Ruby中的闭包概念, 它和封闭作用域的方法(使用def关键字定义的方法)有什么不同。

    ⚠️ Ruby中定义了三个地方为封闭的作用领域(对应三个关键字):

    • 类定义 class
    • 模块定义 module
    • 方法def

    区别于一般的方法,闭包在Ruby中以代码块的形式出现,它在Ruby世界中几乎无处不在,充当了一等公民。这种区分,不仅使我们的Ruby代码更加优雅,增添了可读性,还使得我们的编码过程更加简单。

  • 相关阅读:
    访当当网的图标
    关于手触
    关于位置——CSSOM视图模式(CSSOM View Module)相关整理
    js 进制 转换
    函数的引用, 关于内存的开销
    一些
    HTML特殊符号对照表
    页面选中文字的javascript
    获取元素相对于页面的位置 和 页面高度 和 页面滚动高度
    i+1 和 i++ 的区别
  • 原文地址:https://www.cnblogs.com/chentianwei/p/11438465.html
Copyright © 2020-2023  润新知