当前位置: 传客网 > Ruby方法,Proc, lamda和闭包

Ruby方法,Proc, lamda和闭包

2016-12-30 作者:磊子

方法:
定义简单方法
关键字def用于定义方法,在之后是方法名和可选的参数列表,参数名列表会用一对圆括号括住,构成方法主体的代码放在参数列表之后,end关键词用于表明方法定义的结束。参数名在方法代码体中像变量名一样使用。
#Define a method named 'factorial' with a single parameter 'n'
####阶乘#####
def factorial(n)
  if n<1
    raise "argument must be >0"
  elsif n==1
    1
  else
    n*factorial(n-1)
  end
end
puts factorial(6)
#=>720

方法返回值:最后一行的值或者是return后的表达式

方法和异常处理就是按照raise异常传播

在对象上调用方法:用“.”例如first=text.index(pattern)

定义单键方法
如果直接def则定义了全局函数,如果放到类里面就会成为该类的实例方法,但是——可以使用def语句为一个特的对象定义方法,之需要简单的在def关键词后加上一个求职结果为对象的表达式,在这个表达式之后需要一个句点符号和要定义的方法名
o="message"
def o.printme
puts self
end
o.printme

取消方法定义
可以使用undef语句取消定义
###取消方法定义####
def sum(x,y);x+y;end
puts sum(1,2)
undef sum
undef也可以取消在类中的使用,用来取消实力方法的定义,有趣的是,undef也可以用于取消继承方法的定义,而不一样想所继承的类中该方法的定义,加入类A定义了一个方法m,而类B也继承了m方法,如果不想让类B继承方法m,可以在子类的代码中使用undef取消m的定义
####=>undef并不常见,很多时候并不取消只是新定义一种方法,在一个方法或者模块中,还可以使用undef_method(它是Module的私有方法)来取消方法定义,采用此方式,需要把代表要取消方法名字的符号(symbol)传给undef_mothod方法


方法名
习惯上通常是小写字母开头,习惯:可以在最后加一个?方法在列表为空返回true,这样的方法被称为,还可以再之后家一个!表明需要警惕这个方法,通常是可变方法,可能改变对象的内部结构,所以!通常是用于提醒程序员谨慎使用这个方法


操作符方法(略)

方法别名:用alias方法将已有的方法定义成别的名字
alias aka also_known_as # alias new_name existing_name
#!定义别名并不是重载

方法和圆括号
在绝大多数方法调用中,ruby允许省略圆括号,在简单的情形下,这让代码看起来很整洁但是在复杂情况下会造成混乱

可选的圆括号:
ruby是一种强面向对象的语言,他的对象被完全封装,与他进行交互的唯一方法就是调用其方法,所以下面的代码是圆括号省略的表现
#
greeting="Hello"
size=greeting.length
#
而不是调用其属性,这里也体现出了圆括号可以省略,通常没有参数会被省略
而且,定义方法时可以:
#
def sum x,y
x+y
end
#

必须的圆括号:会引起歧义要严格使用例如
f g x,y Ruby解释器会把他解释称f(g(x,y))但是会发出一个警告
还有二义性,比如puts(sum x,y)时表示puts(sum(x),y)还是puts(sum(x+y))
所以在使用的时候要注意二义性


方法参数(参数列表)
参数默认值:
在定义方法的时候,可以为一些或全部参数制定默认值,这样调用是就可能使用比较少的参数:
###指定参数初始值####
def prefix(s,len=1)
  s[0,len]
end
puts prefix("Ruby",3)
puts prefix("Ruby")
#=>
Rub
R

可变参数列表和数组
又是我们想编写可以接受任意多个参数的方法,要做到这个需要在某个参数前面放一个*,表示一个数组,huan可以传零个或者多个参数
def max(first,*rest)
  max=first
  rest.each{|x| max=x if x>max}
  max
end

puts max(1)
puts max(1,2)
puts max(1,2,3)

把方法传递数组参数:如果想传递数组对象给方法,,可以用*符号传递例如m=max(*data)或者,那些返回值为数组的参数,例如x,y=cartesian(*polar(x,y)),还可以将字符串变成数组传递例如
max(*"Hello World".each)

实参到形参的映射(略)

哈希表作为有名参数
当一个方法有多余两三个参数的时候,程序员很难记住参数顺序,一些语言允许为参数指定对应的采纳和宿命,Ruby不支持这种句法,不过如果方法使用哈希对象作为采纳书(或者参数之一),可以得到近似的功能
####哈希表作为有名参数####
def sequence(args)
  n=args[:n]||0
  m=args[:m]||1
  c=args[:c]||0
  a=[]
  n.times{|i| a<<m*i+c}
  a
end
puts sequence({:n=>3,:m=>5})

代码块参数
前面已经说过,例如迭代器是一个以迭代器做输入的方法,每个方法调用都要紧跟一个代码块,每个关联代码的方法可以通过yield语句调用代码块中的代码,代码块的特征之一是匿名性,他们并非被一传统的形式传给方法,他们没有名字,通过关键字而非方法被调用,如果希望跟明确的方法来控制一个代码块可以在方法后面加上一个参数,并用&做这个参数名的前缀,这样这个就会指向传给方法的代码(如果有的话),这个参数的值是一个Proc对象,他不是通过yield调用,而是直接通过Proc的call来调用,例如:
#####代码块参数#####
def sequence3(n,m,c,&b)
  i=0
  while(i<n)
    b.call(i*m+c)#填入对应的代码块
    i+=1
  end
end
sequence3(5,2,2){|x| puts x}
#=>
2
4
6
8
10
注意,这种使用&符号的方式仅仅是改变了方法定义,方法调用的方式保持不变,只是把代码块参数放到了方法定义的圆括号之内,而代码本身还是在方法定义的括号之外完成的
显式的表示
def sequence3(n,m,c,b)
  i=0
  while(i<n)
    b.call(i*m+c)
    i+=1
  end
end
p=Proc.enw{|x| puts x}
sequence3(5,2,2,p){|x| puts x}

在方法调用时使用&
我们可以看到如何在方法定义中使用*把多个参数打包到一个数组中,而且可以在方法调用时使用*来表明一个数组应该被解开,之每个元素成为一个独立参数;&也可以在方法调用时使用,先前我们之看到如何在方法定义中使用&,他把一个普通的代码块定义为一个在方法中可以使用的有名Proc对象,在方法调用时,如果在一个Proc对象前使用&,在这个调用中,就会像对一个普通代码块一样处理该Proc对象
首先我们看一下代码:
######在方法调用中使用&#####
a1,b1=[1,2,3],[4,5]
summation=Proc.new{|total,x| total+x}
puts sum=a1.inject(0,&summation)
puts sum=b1.inject(sum,&summation)
如果在方法调用中使用&,他必须被用于修饰方法的最后一个参数,代码块可以与任何一个方法关联起来,即使这个方法并不需要一个代码块,也没有一句yield语句,任何方法调用都可以用一个&参数作为最后一个参数
##给定一个字符串数组,在一个新传见的数组中把他们都转换成大写形式
words=['and','but','car']
uppercase=words.map &:upcase#upcase方法作为代码块
puts upper=words.map{|w| w.upcase}
puts
puts uppercase

Proc, lamda和闭包(后续补充)


相关推荐

  • 深入类中的方法[11] - 方法的调用约定

    因为使用方法参数的不同,所以有了调用约定.譬如Delphi默认的是从左到右读取参数;WindowAPI是从右到左读取参数.如果没有调用约定,Delphi就无法使用由C语言编写的WindowAPI;如果没有调用约定,别的语言也无法使用由Del

  • [转]C# 线程同步技术(一)之 Join 方法

    【总结】C#线程同步技术(一)之Join方法最近工作闲暇之际,翻阅了以前保存的电子书《C#多线程编程手册》,发现此书同步技术这块写的甚好,于是参考此书并结合实例,对同步技术做一下总结和分析,也算是读书笔记与心得体会吧,并与大家分享。书中提到

  • 华为EMUI5.0 获取 root 方法

    华为EMUI5.0目前root方法是刷TWRP,然后使用TWRP刷入Chainfire的SuperSU或者phh的Superuser。你需要支持Nougat版本的TWRP,但是在刷入Chainfire的SuperSU过程中会直接导致设备重启

  • 浅谈Coolite  方法调用

    今天需要做个复选框删除,碰到了一个小难题,然后我一通乱写,居然误打误撞吧问题给解决了.堵塞的思维一下活跃起来,不禁想把Coolite的方法调用写下来.还是以按钮说起吧:Coolite的按钮方法调用很灵活,它可以非常方便的调用javascri

  • jQuery load() 方法实现加载远程数据

    JQueryload()方法是简单但强大的AJAX方法。load()方法从服务器加载数据,并把返回的数据放入被选元素中。语法:$(selector).load(URL,data,callback);必需的URL参数规定您希望加载的URL。可

  • Http get post 方法的区别(转)

    一原理区别一般在浏览器中输入网址访问资源都是通过GET方式;在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认为GET提交Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,D

  • [原]iOS自定义多参数类型方法[UIAlertView 方法实现]

    [原]iOS自定义多参数类型方法2015-4-1阅读135评论0前几天做自定义UIAlertView的时候,想仿造系统自带的初始化方法做一个AlertView,里面涉及到不确定多参数的设置和使用问题。这里做一下记录。我自定义了一个方法:-(

  • JavaScript setTime() 方法

    定义和用法setTime()方法以毫秒设置Date对象。语法dateObject.setTime(millisec)参数描述millisec必需。要设置的日期和时间据GMT时间1997年1月1日午夜之间的毫秒数。这种类型的毫秒值可以传递给D

  • 网页元素垂直居中 css 方法和Js方法

    垂直居中的方法:css:#div{position:absolute;height:x;width:y;top:50%;left:50%;margin-top:x/2;margin-left:y/2;}这种方法只是在可视的区域是居中的,就是

  • myeclipse 8.5-9.0 安装 svn 方法

    方法总结方法一:在线安装1.打开HELP-&gt;MyEclipseConfigurationCenter。切换到SoftWare标签页。2.点击AddSite打开对话框,在对话框Name输入Svn,URL中输入:http://su

  • 如何支持<书桥舒桥>爱心捐书? 方法 01 - 方法07

    方法01<买新书>去就近的书店,按自己的能力,买适合12歲以下小朋友合看的课外书,寄去以下地点『云南省丽江市玉龙县拉市乡安上村绿色家园,邮编674107,刘俪波电话13308889507註明<书桥舒桥>』或『雲南丽江

  • 2.2 方法和属性

    2.2方法和属性表2-1显示了XMLHttpRequest对象的一些典型方法。不要担心,稍后就会详细介绍这些方法。表2-1 标准XMLHttpRequest操作方法描述abort()停止当前请求getAllResponseHeaders()

  • flash as3 键盘控制角色八方向行走 多人游戏 方法2整理版

    方法2根据数组KeyAry数组的第键盘码个元素(==)就被赋值为true,然后在isDown处返回那个元素是否为true。据此判断设置人物行走状态。在EnterFrame里判断键盘是否被按下。不断调用isDown函数返回。比在PressKe

  • 大道至简的数据体系构建 方法 论分析挖掘

    大道至简的数据体系构建方法论分析挖掘很多企业已经意识到,一个系统化的数据体系将是数据化运营的核心支柱。那么,企业该如何清晰地打造自己的数据体系呢?作者将根据多年经验总结用简朴的语言告诉读者一套大道至简的方法_论。本文是“数据化运营方法_论系

  • Render 方法  呈现 ASP.NET 服务器控件

    Render方法呈现ASP.NET服务器控件呈现表示在显示器表面上创建视觉表示形式的进程。在Web请求时,实际的呈现是由客户端的Web浏览器或其他查看设备执行的。ASP.NET页框架的任务是发送HTML(或使用XML或WML这样的其他标记语

  • JS 最简单的AJAX实例, GET 和 POST 方法

    申明:一定要打开服务器再在服务器域名下输入以下文件的地址,否则不能完成AJAX的传输以下列举出的所有文件均放在同一级目录下(同一个文件夹下),否则自行修改路径。Get方法:1.有两种组合:一种是文件1+文件2;另一种是附件1+文件2。内容其

  • Java 方法的访问说明符 public,protected,default,private

    刚开始学习Java,总是把这几个弄混,现在总结一下:方法的访问说明符:其实就是用来修饰方法的一些词语,从这些修饰词中,我们可以了解到这个类型的访问权限。(public,protected,default,private)另外Java中,还存

  • 第八章 方法心得-java

    编程划分:1.面向机器编程汇编2.面向过程c3.面向对象javac++4.面向关系关于java面向对象万物皆为对象那么什么是对象方法与属行就是对象java方法与调用return:结束本方法break:结束本层并跳出本循环continue:结

  • jquery mobile 方法收集

    转载为---为理想中的状态起航!jquerymobile方法收集.1、在列表项和按钮上禁用文本截断如果你的列表项或者按钮上是一个很长的文本,它将会被jQueryMobile自动截断,要禁用这个截断设置,需要在CSS选择器上添加属性"whit

  • jQuery Ajax 方法调用 Asp.Net WebService 的详细例子

    这很常用,搜索了一下博客园的“找找看”和谷歌,看到大部分都是转载于一两篇文章(而且来源还不是博客园),有的是简单的说一点无法运行,给初学者的调试和学习带来不方便,我在这里将jQueryAjax调用Aspx.NetWebService的几个常

返回
顶部