• 有趣的Ruby-学习笔记4


    Ruby块

    块。在我看来就是插入一段可变的函数
    block_name{
       statement1
       statement2
       ..........
    }

    看起来不知道是什么,只是别急,继续往下看。
    块函数通过yield来调用

    yield 语句

    yield英文就是 屈服。放弃,不知道为什么用这个单词。难道是 此处函数就放弃了控制权?
    样例
    #!/usr/bin/ruby
    # -*- coding: UTF-8 -*-
    
    def test
       puts "在 test 方法内"
       yield
       puts "你又回到了 test 方法内"
       yield
    end
    test {puts "你在块内"}
    运行了这段后的效果是
    在 test 方法内
    你在块内
    你又回到了 test 方法内
    你在块内
    在yield的部分运行了你调用时传入的块语句。

    所以yield是不是看起来没啥用?继续往下看

    yield能够带參数

    您也能够传递带有參数的 yield 语句。下面是一个实例:
    #!/usr/bin/ruby
    # -*- coding: UTF-8 -*-
    
    def test
       yield 5
       puts "在 test 方法内"
       yield 100
    end
    test {|i| puts "你在块 #{i} 内"}

    块和方法

    假设方法的最后一个參数前带有 &,那么您能够向该方法传递一个块,且这个块可被赋给最后一个參数。假设 * 和 & 同一时候出如今參数列表中,& 应放在后面。
    #!/usr/bin/ruby
    
    def test(&block)
       block.call
    end
    test { puts "Hello World!"}
    是不是令你想起了javascript里面的回调函数?
    结合上yield传參,能够实现传入一段回调函数,并且该回调函数中能够依据函数运行的过程中传入的不同參数做出不同的行为。
    总算感觉块这个特性有点用了。。


    BEGIN 和 END 块

    BEGIN和END块就像java中的拦截器,一个是before拦截器。一个是after拦截器
    #!/usr/bin/ruby
    
    BEGIN { 
      # BEGIN 代码块
      puts "BEGIN 代码块"
    } 
    
    END { 
      # END 代码块
      puts "END 代码块"
    }
      # MAIN 代码块
    puts "MAIN 代码块"
    一个程序能够包括多个 BEGIN 和 END 块。BEGIN 块依照它们出现的顺序运行。END 块依照它们出现的相反顺序运行。

    当运行时,上面的程序产生产生下面结果:

    BEGIN 代码块
    MAIN 代码块
    END 代码块

    Ruby模块

    模块(Module)是一种把方法、类和常量组合在一起的方式。模块(Module)为您提供了两大优点
    • 模块提供了一个命名空间和避免名字冲突
    • 模块实现了 mixin 装置
    模块(Module)定义了一个命名空间,相当于一个沙盒,在里边您的方法和常量不会与其它地方的方法常量冲突。


    • 模块相似与类,但有一下不同模块不能实例化
    • 模块没有子类
    • 模块仅仅能被还有一个模块定义
    module Identifier
       statement1
       statement2
       ...........
    end
    模块常量命名与类常量命名相似,以大写字母开头。方法定义看起来也相似:模块方法定义与类方法定义相似。

    样例

    #!/usr/bin/ruby
    
    # 定义在 trig.rb 文件里的模块
    
    module Trig
       PI = 3.141592654
       def Trig.sin(x)
       # ..
       end
       def Trig.cos(x)
       # ..
       end
    end

    require 语句

    最终看到require语句了。没有require功能简直是不能写代码啊,所以结合上require,module功能是我看到最重要的功能了
    实例
    $LOAD_PATH << '.'
    
    require 'trig.rb'
    
    y = Trig.sin(Trig::PI/4)
    注意这句话  $LOAD_PATH << '.'  这句话是把require的路径定到当前的文件路径,我刚開始require总是失败就是由于没有这句话
    假设不想用 $LOAD_PATH 还能够使用 require_relative 方法
    require_relative 'trig.rb'
    
    y = Trig.sin(Trig::PI/4)

    也能够!并且我更喜欢 require_relative 由于更好记

    include 语句

    您能够在类中嵌入模块。

    你肯定跟我会有一样的疑问:“但是,我都有require了为什么还要include?!”


    假设下面代码写在 support.rb 里面
    module Week
       FIRST_DAY = "Sunday"
       def Week.weeks_in_month
          puts "You have four weeks in a month"
       end
       def Week.weeks_in_year
          puts "You have 52 weeks in a year"
       end
    end

    我们来嵌入一下
    #!/usr/bin/ruby
    $LOAD_PATH << '.'
    require "support"
    
    class Decade
    include Week
       no_of_yrs=10
       def no_of_months
          puts Week::FIRST_DAY
          number=10*12
          puts number
       end
    end
    d1=Decade.new
    puts Week::FIRST_DAY
    Week.weeks_in_month
    Week.weeks_in_year
    d1.no_of_months
    你会发现,有没有那行 include Week 代码运行结果根本就没有差别!

    那include有什么卵用呢?!

    要解释include到底有什么用,就要介绍一下 ruby 的 mixins 特性

    Ruby 中的 Mixins

    Ruby中并没有多重继承,取而代之的是Mixin。当你将模块include到类定义中。模块中的方法就被mix到了类里面
    实例代码,看A, B 怎样被mix到 Sample里面
    module A
       def a1
       end
       def a2
       end
    end
    module B
       def b1
       end
       def b2
       end
    end
    
    class Sample
    include A
    include B
       def s1
       end
    end
    
    samp=Sample.new
    samp.a1
    samp.a2
    samp.b1
    samp.b2
    samp.s1

    include & require & load


    原来include跟require有下面的差别(这边还要提到load方法)
    • require不须要跟上后缀,会自己主动识别 xxx.rb
    • require假设调用2次就会报错,假设要调用多次就用load,但是用load得写上文件后缀名
    • require一般用于载入库文件,load一般用户载入配置文件
    • include 用于把一个文件里的模块mix到类中
    • include并不会把module的实例方法复制到类中,仅仅是做了引用,包括module的不同类都指向了同一个对象。假设你改变了module的定义。即使你的程序还在运行,全部包括module的类都会改变行为

  • 相关阅读:
    spring通过注解依赖注入和获取xml配置混合的方式
    Spring 3.0就这么简单读书笔记
    spring源码测试
    spring文档翻译
    敏感词过滤算法
    mongodb的地理空间索引如何在solr中体现
    mongodb的地理空间索引常见的问题
    mysql的distinct理解
    zookeeper管理solr的配置文件
    驾校理论考试
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6992521.html
Copyright © 2020-2023  润新知