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的类都会改变行为

有趣的Ruby-学习笔记4的更多相关文章

  1. Ruby学习笔记4: 动态web app的建立

    Ruby学习笔记4: 动态web app的建立 We will first build the Categories page. This page contains topics like Art, ...

  2. ruby学习笔记(1)-puts,p,print的区别

    ruby学习笔记-puts,p,print的区别 共同点:都是用来屏幕输出的. 不同点:puts 输出内容后,会自动换行(如果内容参数为空,则仅输出一个换行符号):另外如果内容参数中有转义符,输出时将 ...

  3. ruby 学习笔记 1

    写ruby blog  系统的记录下.也是对我学ruby的点滴记录. 先介绍下我的学习环境.系统:ubuntu12.04文档:techotopia ,ruby文档,the hard way learn ...

  4. ruby学习笔记(2)-chomp,chop的区别

    还没开始系统性的学习Ruby,最近在看metasploit框架的exploit会涉及到Ruby脚本,也就硬着头皮一遍查阅资料一遍做些笔记吧. Ruby字符串中存在chop和chomp的内置函数.我在h ...

  5. Ruby学习笔记0708

    #!/usr/bin/env ruby class MegaGreeter attr_accessor :names # 初始化這個物件 def initialize(names = "Wo ...

  6. ruby 学习笔记 2 -变量

    变量 在ruby的世界里,变量有5种,全局变量 局部变量 实例变量 常量 类变量以及伪变量 常用的: 全局: 在全局使用,使用$开头,因为是全局的,所以在任何的代码例子中都可以改变其值,造成混乱,所以 ...

  7. Ruby学习笔记

    #!/usr/bin/ruby puts "Hello, Ruby, what is your name?" $name = STDIN.gets puts "Hi, I ...

  8. Ruby学习笔记(二)

    1.block 代码块 do...end 或 {} 构成一个代码块,就像常见的 .each后面跟的代码块. my_nums = [1,2,3] my_double_nums = my_nums.col ...

  9. Ruby学习笔记之升级ruby的版本

    升级ruby版本,有时候安装ruby的版本过低,需要进行升级,例如安装在centos6.7安装fpm需要ruby版本在1.9以上. 0x00 主机环境如下 [root@test ~]# cat /et ...

  10. Ruby学习笔记7: 添加身份验证(adding Authentication)

    我们已经完成了Category & Product页面内容的增删改查,再加入一个身份验证即可成为一个较完整的Rails App了.本文就来完成这个任务. We now need to give ...

随机推荐

  1. centos7 ssh免口令认证登录

    摘要:centos7, xshell, 公钥,  ssh ssh登录方式有口令认证登录和密钥认证登录 接下来本次介绍是ssh密钥登录方式 (1)产生公钥 (2)将公钥放置到centos7的(/root ...

  2. Gym - 100625E Encoded Coordinates 矩阵快速幂

    题意: 一直TLE我也是醉了,,不爽! #include <iostream> #include <cstdio> #include <fstream> #incl ...

  3. 国行Android手机使用google全套GMS服务小结

        由于众所周知的原因,国行手机是不能内置google服务的,但作为铁杆google粉,没有GMS的Android不是完整的Android,NEXUS系列机器又由于各种原因买不到或者不想选购,那么 ...

  4. paste---合并文件的列。

    Linux paste命令用于合并文件的列. paste指令会把每个文件以列对列的方式,一列列地加以合并. 语法 paste [-s][-d <间隔字符>][--help][--versi ...

  5. Vim插件使用技巧(转)

    在 IDEA Intellij小技巧和插件 一文中简单介绍了一下IdeaVim插件.在这里详细总结一下这个插件在日常编程中的一些常用小技巧.供有兴趣使用这个插件,但对Vim还不十分熟悉的朋友参考.当然 ...

  6. 洛谷——P1043 数字游戏

    https://www.luogu.org/problem/show?pid=1043 题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要 ...

  7. GridControl添加右键菜单

    private void gridView1_MouseDown(object sender, MouseEventArgs e) { GridHitInfo vi = gridView1.CalcH ...

  8. leetcode笔记:Sort Colors

    一. 题目描写叙述 Given an array with n objects colored red, white or blue, sort them so that objects of the ...

  9. OpenCASCADE7.3.0 is available for download

    OpenCASCADE7.3.0 is available for download OPEN CASCADE is pleased to announce a new public release ...

  10. Toeplitz matrix 与 Circulant matrix

    之所以专门定义两个新的概念,在于它们特殊的形式,带来的特别的形式. 1. Toeplitz matrix 对角为常数: n×n 的矩阵 A 是 Toepliz 矩阵当且仅当,对于 Ai,j 有: Ai ...