有趣的Ruby-学习笔记4
Posted liguangsunls
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有趣的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的类都会改变行为
以上是关于有趣的Ruby-学习笔记4的主要内容,如果未能解决你的问题,请参考以下文章
《有趣的二进制:软件安全与逆向分析》读书笔记:在射击游戏中防止玩家作弊
《有趣的二进制:软件安全与逆向分析》读书笔记:在射击游戏中防止玩家作弊