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. 10.MongoDB:将Json数据直接写入MongoDB的方法

    Json转Bson MongoDB中是以Bson数据格式进行存储的,Json字符串没有办法直接写入MongoDB 可以将Json字符串转换成DBObject或者Document,然后写入MongoDB ...

  2. android开源项目---View篇

    本文转载自:http://blog.csdn.net/likebamboo/article/details/19080739 主要介绍那些不错个性化的View,包括ListView.ActionBar ...

  3. Flex与Java通信之HttpService

    flashbuilder4.6.myeclipse10 参考:http://www.cnblogs.com/lovemoon714/archive/2012/05/25/2517684.html 1. ...

  4. 深入解析开源项目之Universal-Image-Loader(二)硬盘---缓存篇

    文件命名: FileNameGenerator,HashCodeFileNameGenerator,Md5FileNameGenerator package com.nostra13.universa ...

  5. 56.ERR! configure error gyp ERR! stack Error: Can't find Python executable "python", you can set the PYTHON env variable.

    Node.js 在安装模块的时候报错,缺少python环境. ERR! configure error gyp ERR! stack Error: Can't find Python executab ...

  6. POJ 2323 贪心

    题意: 思路: 贪 贪 贪 如果当前的c>之前的c+s 那么之前的合适 一直贪下去就好了 //By SiriusRen #include <cstdio> #include < ...

  7. Whitening

    The goal of whitening is to make the input less redundant; more formally, our desiderata are that ou ...

  8. Django模型三

    关联对象操作及多表查询 关联表的数据操作: 一对多: 正向:如果一个模型有外键字段,通过这个模型对外键进行操作叫做正向. 更新: 通过属性赋值 In [1]: from teacher.models ...

  9. 洛谷 P1957 口算练习题

    洛谷 P1957 口算练习题 题目描述 王老师正在教简单算术运算.细心的王老师收集了i道学生经常做错的口算题,并且想整理编写成一份练习. 编排这些题目是一件繁琐的事情,为此他想用计算机程序来提高工作效 ...

  10. [C++11] 默认构造函数

    类通过一个特殊的构造函数来控制默认初始化过程.这个函数就是默认构造函数.默认构造函数无需不论什么实參. 我们能够显示的定义默认构造函数也能够让编译器为我们生成默认构造函数. 默认构造函数以例如以下规则 ...