博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
有趣的Ruby-学习笔记4
阅读量:3555 次
发布时间:2019-05-20

本文共 3098 字,大约阅读时间需要 10 分钟。

Ruby块

块,在我看来就是插入一段可变的函数
block_name{   statement1   statement2   ..........}
看起来不知道是什么,不过别急,继续往下看。
块函数通过yield来调用

yield 语句

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

yield可以带参数

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

块和方法

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

BEGIN 和 END 块

BEGIN和END块就像java中的拦截器,一个是before拦截器,一个是after拦截器
#!/usr/bin/rubyBEGIN {   # 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)   # ..   endend

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"   endend
我们来嵌入一下
#!/usr/bin/ruby$LOAD_PATH << '.'require "support"class Decadeinclude Week   no_of_yrs=10   def no_of_months      puts Week::FIRST_DAY      number=10*12      puts number   endendd1=Decade.newputs Week::FIRST_DAYWeek.weeks_in_monthWeek.weeks_in_yeard1.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   endendmodule B   def b1   end   def b2   endendclass Sampleinclude Ainclude B   def s1   endendsamp=Sample.newsamp.a1samp.a2samp.b1samp.b2samp.s1

include & require & load

原来include跟require有以下的区别(这边还要提到load方法)
  • require不需要跟上后缀,会自动识别 xxx.rb
  • require如果调用2次就会报错,如果要调用多次就用load,但是用load得写上文件后缀名
  • require一般用于加载库文件,load一般用户加载配置文件
  • include 用于把一个文件中的模块mix到类中
  • include并不会把module的实例方法拷贝到类中,只是做了引用,包含module的不同类都指向了同一个对象。如果你改变了module的定义,即使你的程序还在运行,所有包含module的类都会改变行为

转载地址:http://ocdrj.baihongyu.com/

你可能感兴趣的文章
实现自己的权限管理系统(二):环境配置以及遇到的坑
查看>>
实现自己的权限管理系统(四): 异常处理
查看>>
实现自己的权限管理系统(十):角色模块
查看>>
实现自己的权限管理系统(十二):权限操作记录
查看>>
实现自己的权限管理系统(十三):redis做缓存
查看>>
实现自己的权限管理系统(十四):工具类
查看>>
JavaWeb面经(一):2019.9.14
查看>>
JavaWeb面经(二):2019.9.16 Synchronized关键字底层原理及作用
查看>>
牛客的AI模拟面试(1)
查看>>
深入浅出MyBatis:MyBatis解析和运行原理
查看>>
Mybatis与Ibatis
查看>>
字节码文件(Class文件)
查看>>
java中的IO流(一)----概述
查看>>
StringBuilder
查看>>
集合,Collection
查看>>
泛型详解
查看>>
泛型实现斗地主
查看>>
List集合
查看>>
ArrayList集合,LinkedList集合,Vector集合
查看>>
HashSet集合
查看>>