Ruby方法,Proc, lamda和闭包

方法:
定义简单方法
关键字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()

你的评论

就没有什么想说的吗?

©2017传客网    琼ICP备15003173号-2    

本站部分文章来源于互联网,版权归属于原作者。
本站所有转载文章言论不代表本站观点,如是侵犯了原作者的权利请发邮件联系站长(weishubao@126.com),我们收到后立即删除。
站内所有资源仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您自己承担!

X