方法和代码块

在Ruby中。{}或do...end之间的代码是一个代码块。
代码块只能出如今一个方法的后边,它紧接在方法最后一个參数的同一行上,一般由yieldkeyword调用代码块中的代码。

方法是一个有名的代码块。是与一个或者多个对象相关联的參数化代码。

调用方法时必需要给出方法名、所在对象(接受者),以及零个或者多个參数值,方法中最后一个表达式的值将作为方法调用的返回值。

代码块不是ruby可操作的对象。一般我们用一个Proc对象代表一个代码块。
有两种方式的Proc对象,一种是proc。一种是lambda,他们都是闭包:他们会保持定义时所在范围内的局部变量,即使在外部范围被调用时。他们也能够对这些变量进行訪问。

方法的定义就不说了。前面有说过。

方法名以小写字母开头。假设方法名超过一个字母,一般用下划线切割开来。

方法可选的圆括号

在很多方法调用中圆括号是可省略的,如 puts “hello” 和 puts (“hello”)是一样的。
ruby是一种强面向对象的语言。他的对象被全然封装。与他们交流的唯一方式就是调用他们的方法。所以 len = "hello".length 事实上是 len = “hello”.length(),只只是把圆括号省略掉了,你看起看好像是他的属性訪问。

普通情况下,假设參数超过一个,最好不要省略圆括号。

代码块參数

传统方式就是代码块直接跟在方法后面。并用yield来调用代码块。
在函数里面的有一条yield语句。到时候运行的时候能够运行函数外的block。并且这个block能够有自己的context, 感觉有点像callback,又有点像c里面的宏定义。

有人说yield就充当一个占位符的作用,函数先给一个占位符,这个函数如同一个纯需函数一样不能直接调用,必须用block把这个位坑给添了才干使用这个函数。  

def block_test(num)
if block_given?
#yield #无參数
yield (num)
else
puts num
end end #block_test(1)
#block_test(2) { puts "this is a block ..."}
block_test(2) {|x| puts x * 2}

或者在方法的后面加上一个參数,并用&作为这个參数的前缀,这样这个參数就会指向传给方法的代码块,这个參数的值是个Proc对象。它不是通过yield调用的,而是call调用的。

def proc_test(num,&b)

	if block_given?
#b.call
b.call(num * 3)
else
puts "no block"
end end #proc_test(1)
#proc_test(1) {puts "this is a block"}
proc_test(1) {|x| puts x * 2}

创建Proc对象的3种方式

Proc.new
假设在方法的最后一个形參前添加一个”&”符号,那么Ruby会把这个形參作为一个Proc对象处理。
全部的Proc对象都有一个call的方法,当调用这种方法时,会运行创建这个Proc对象时定义的代码块。
假设Proc.new不带參数。返回一个proc方式的Proc对象。

Proc对象有proc方式、lambda方式。

假设Proc.new带參数。返回一个关联代码块的Proc对象,这个对象代表这个关联的代码块。

p = Proc.new { puts "hello,dear..."}

def proc_test(&pp)
pp.call
end

Kernel.lambda
lambda方法返回的是一个lambda方式的Proc对象。
lambda方法不带參数,可是在调用时必须关联一个代码块。

puts lambda{|x| x + 10}.call(2)

Kernel.proc
这个1.8是lambda的同义词,1.9是Proc.new的同义词。
这个就不说了。

代码块,proc。lambda的return
一个代码块中的return语句不仅会从调用代码块的迭代器中返回,还会从调用迭代器的的方法中返回。

def test
puts "start.."
2.times {puts "hello,";return}
puts "end..." #不会别打印
end

proc和代码块相似,所以假设在调用的proc中运行一个return语句,它会试图从代码块所在的方法中返回。
而在lambda中的return语句只时从lambda自身返回。

def pro_fun (msg)
puts "start..." p = Proc.new {puts "hello,#{msg}";return} #会从代码块所在的方法pro_fun中返回
p.call puts "end..."
end def lambda_fun(msg)
puts "start.."
lam = lambda {puts "hello,#{msg}";return} #只返回自身
lam.call
puts "end..."
end def test
puts "test start"
#pro_fun "song"
lambda_fun "song"
puts "test end"
end test

ruby简单的基础 5的更多相关文章

  1. ruby简单的基础 4

    后缀标点符号 =结尾假设方法名字以=结尾的,那么在调用此方法时能够省略这个=. ?结尾作为一个实用惯例,那些返回布尔值的方法通常都有一个以问号结尾的名字. .结尾这个命名惯例通常时对两种方法区分:以感 ...

  2. ruby简单的基础 2

    1.代码块 代码块是用大括号或者do...end括起来的一系列代码.{ #this is a block} do #this is a blockend [1,2,3,4,5].each {|i| p ...

  3. Ruby自学笔记(二)— Ruby的一些基础知识

    Ruby安装好之后,我们就可以来实践Ruby语言了. 以下是一些学习到的简单基础知识: 1. 如何执行Ruby文件? 我们编写的Ruby文件是以rb为后缀名的,例如:XXX.rb.当要执行ruby文件 ...

  4. ruby迭代起基础

    “循环”会用在程序中的各种地方.而在循环的地方善用“迭代器”,则是熟练进行Ruby程序设计的重要关键. 不过,迭代器确实有比较抽象的地方,语法也有点怪异(尤其是yield的用法),光是依靠文字说明.看 ...

  5. ruby简单的基本 3

    类 Ruby一切都是对象,它包含了一个恒定.例如,可以使用.class物业查看对象的类型,你可以看一下1.class.你会发现常1类型是Fixnum,1但它是Fixnum的一个例子. Ruby本类cl ...

  6. 【Ruby】【基础】

    # [Ruby 块]=begin1 块由大量代码构成2 块中代码包含在{}内3 从与其相同名称的函数调用4 可以使用yield语句调用块=enddef test p '在test方法内' yield ...

  7. [您有新的未分配科技点]博弈论进阶:似乎不那么恐惧了…… (SJ定理,简单的基础模型)

    这次,我们来继续学习博弈论的知识.今天我们会学习更多的基础模型,以及SJ定理的应用. 首先,我们来看博弈论在DAG上的应用.首先来看一个小例子:在一个有向无环图中,有一个棋子从某一个点开始一直向它的出 ...

  8. SQLHelper简单版(基础版)

    using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; usin ...

  9. ruby简单的基本 6

    模 像类似的模块,那里 class method 和 instance method.module 没有new不能生成对象的例子其中 class method 所谓的模块在模块化的方法,它能够直接调用 ...

随机推荐

  1. SQL Server 空间监测

    数据库文件型: select * from sys.dm_db_file_space_usage;      go                                           ...

  2. poj1484---判断保险丝是否烧断

    题目输入要求: 2 2 10 //设备数n  接下来的操作数m   保险丝能承受最大电流c5 //电器1的电流7 //2的电流1 //反转开关12 //反转开关2 思路:设置一个flag数组,记得每次 ...

  3. 将Dictionary序列化为json数据 、json数据反序列化为Dictionary

    需要引用System.Web.Extensions  dll类库 /// <summary> /// 将json数据反序列化为Dictionary /// </summary> ...

  4. 华为OJ机试训练(一)

    题目1 -- 通过输入英文句子.将每一个单词反过来,标点符号顺序不变.非26个字母且非标点符号的情况就可以标识单词结束. 标点符号包含,.!? 比如输入:Hello, I need an apple. ...

  5. 使用Vitamio打造自己的Android万能播放器(3)——本地播放(主界面、播放列表)

    前言 打造一款完整可用的Android播放器有许多功能和细节需要完成,也涉及到各种丰富的知识和内容,本章将结合Fragment.ViewPager来搭建播放器的主界面,并实现本地播放基本功能.系列文章 ...

  6. C#命名空间详解namespace

     命名空间是一个域,这在个域中所有的类型名字必须是唯一的,不同的类型分组归入到层次化的命名空间, 命名空间的好处是:1.避免名字冲突,2.便于查找类型名字. 如:System.secruity.Cry ...

  7. web基础-web工作原理,http协议,浏览器缓存

    1,web工作原理 2,http协议 3,浏览器缓存 4,cookie和session -------------------------------------------------------- ...

  8. html教程系列--form frameset

    <font> 标签: 规定文本的字体.字体尺寸.字体颜色.不建议直接使用,可以使用样式表替代. <footer> 标签:定义公用的底部信息.通常包含文档的作者.版权信息.使用条 ...

  9. 【转】SQL Server查询字段说明

    select c .name, isnull(ETP .value, '') as Des FROM syscolumns c inner join systypes t on c. xusertyp ...

  10. Neo4j简介

    Neo4j简介 发表于2013年3月16日 11:52 p.m.    位于分类图数据库与图并行计算 现实中很多数据都是用图来表达的,比如社交网络中人与人的关系.地图数据.或是基因信息等等.RDBMS ...