`
orez88
  • 浏览: 3332 次
  • 性别: Icon_minigender_1
  • 来自: 江苏
最近访客 更多访客>>
社区版块
存档分类
最新评论

Procs and Lambdas (1)

    博客分类:
  • ruby
阅读更多

block在ruby里是一个词詓的概念,它不是对象,不能被对象操作,但是它能通过一个proc或者是一个lambda表现出来。Procs的行为像block(block-like behavior),lambdas的行为更像一个方法(method-like behavior)。但是两者都是Proc对象,这点可以通过使用class方法看出来。

创建Proc对象:

1,通过使用&前缀的方法参数创建一个proc

def makeproc(&p)  # Convert associated block to a Proc and store in p
  p               # Return the Proc object
end

adder = makeproc {|x,y| x+y }

sum = adder.call(2,2)  # => 4

 这种方式创建的Proc objects是proc,不是lambda,每一个Proc对象都有一个call方法,后面我们会看到多种call方法的语法糖。

2,使用Proc.new

  Proc.new创建的也是proc,而不是lambda,这是最常见的创建一个proc的方法

p = Proc.new {|x,y| x+y }

 这里有一个特殊的用法值得一提:

def invoke(&b)     def invoke
  b.call                  Proc.new.call
end                      end

 上面两个写法是一个效果,什么意思呢:

irb(main):001:1>def invoke
irb(main):002:1> Proc.new.call
irb(main):003:1> end
=> nil
irb(main):004:0> invoke { puts "hello"}
hello
=> nil

 3,Kernel.lambda

lambda是kernel模块的一个方法,所以它的行为像一个全局“函数”。由lambda创建的的Proc对象是一个lambda而不是proc :

is_positive = lambda {|x| x > 0 }

 在ruby1.8里面,Kernel.proc这个全局的proc方法是lambda方法的别名,它也返回一个lambda。ruby1.9修改了这一用法。1.9里proc是Proc.new的别名,因此,最好不要在1.8中使用proc这个全局的方法

irb(main):005:0> proc{ puts "a"}
=> #<Proc:0x8b91d44@(irb):5>
irb(main):006:0> ->{}
=> #<Proc:0x8b8ee64@(irb):6 (lambda)>

 lambda直接量:

1.9里出现了lambda直接量新的语法:

succ = ->(x){ x+1 }

succ.call(2)    # => 3

 lambda的参数作用域:

irb(main):017:0> x,y=1,2
=> [1, 2]
irb(main):018:0> f=->{puts x,y}
=> #<Proc:0x89929f8@(irb):18 (lambda)>
irb(main):019:0> f.call
1
2
=> nil
irb(main):020:0> p=->{x=11,y=22}
=> #<Proc:0x8989808@(irb):20 (lambda)>
irb(main):021:0> p.call
=> [11, 22]
irb(main):022:0> puts x,y
11
22
22
=> nil
#可以看出,lambda并没有象方法和类那样开辟了一个新的作用域,lambda周围
#的变量在lambda中是用定义的

 在ruby1.9里,你可以自行定义lambda的块级作用域,这些lambda的本地变量放在参数列表的“;”之后

irb(main):026:0> i=3
=> 3
irb(main):027:0> f=->(x,y;i,j,k){j=4;k=5;puts x,y,i,j,k}
=> #<Proc:0x88d03bc@(irb):27 (lambda)>
irb(main):028:0> f.call(1,2)
1
2
    #i ?
4
5
=> nil
irb(main):029:0> puts i,j,k
NameError: undefined local variable or method `j' for main:Object
	from (irb):29
	from /usr/local/bin/irb:12:in `<main>'

 lambda的更简洁的写法:

f = -> x,y; i,j,k { ... }
data.sort {|a,b| b-a }   # The block version
data.sort &->(a,b){ b-a } # The lambda literal version

 Procs和Lambdas的调用:

#使用call
f = Proc.new {|x,y| 1.0/(1.0/x + 1.0/y) }
z = f.call(x,y)
#用“[]”,有点像方法的调用方式
z = f[x,y]
#使用“.()”,看起来像是调用一个没有方法名的方法,“.()”不是一个操作符,不能被
#定义,它是call方法的一个语法糖。任何定义了call方法的对象都可以这样来调用call
#而不仅仅是Proc对象
z = f.(x,y)

irb(main):033:0> class A
irb(main):034:1> end
irb(main):036:0> a=A.new
=> #<A:0x8bc5108>
irb(main):037:0> def a.call str
irb(main):038:1> puts str
irb(main):039:1> end
=> nil
irb(main):040:0> a.("hello")
hello
=> nil

 Proc的目(参数个数):arity方法的使用

lambda{||}.arity        # => 0. No arguments expected
lambda{|x| x}.arity     # => 1. One argument expected
lambda{|x,y| x+y}.arity # => 2. Two arguments expected

#对于下面这种情况,arity返回一个负数,通过~m(或者是-m-1)来计算这个
#lambda至少需要多少个参数
irb(main):043:0> ~-1
=> 0
irb(main):044:0> ~-2
=> 1

lambda {|*args|}.arity        # => -1.  ~-1 = -(-1)-1 = 0 arguments #required
lambda {|first, *rest|}.arity # => -2.  ~-2 = -(-2)-1 = 1 argument #required	  

 在ruby1.8和ruby1.9中,以下情况返回的值是不同的

puts lambda {}.arity  # –1 in Ruby 1.8; 0 in Ruby 1.9
#1.8里当lambda的参数列表为空表示它可以接受任意数目的参数,1.9里表示不接
#受任何带参数的调用,发生带参数调用时会出错
irb(main):046:0> l=->{puts "hello"}
=> #<Proc:0x8b8dfc8@(irb):46 (lambda)>
irb(main):047:0> l.("world")
ArgumentError: wrong number of arguments (1 for 0)
	from (irb):47:in `call'
	from (irb):47
	from /usr/local/bin/irb:12:in `<main>'

以上用法对于proc和lambda都适用,因为它们都是Proc对象,下面来看看Lambdas和Procs的区别

分享到:
评论

相关推荐

    named_proc:命名 procs 和 lambdas

    命名过程 当使用大量 proc 时,命名它们可能会很方便。 它使以后更容易识别它们。 有关使用命名过程的示例,请参阅 gem! 安装 添加到 Gemfile: gem 'named_proc' 命名特效 一个命名的 proc 就像一个普通的 ...

    Mastering Ruby Closures

    The road to Ruby mastery is paved with blocks, procs, and lambdas. To be a truly effective Ruby programmer, it’s not enough just to understand these features—you need to know how to use them in ...

    ruby-main.zip

    4. ** Blocks, Procs 和 Lambdas**:Ruby提供了三种代码块结构:Blocks(匿名函数)、Procs(可存储的代码块)和Lambdas(类似于函数)。它们可以作为参数传递,增强了代码的灵活性。 5. **Gem生态系统**:Ruby的...

    有性能参数输出的check_procs

    解决nagios安装后输出process不能出图,这是重新编译后的check_procs,直接替换原来的就可以出图了

    ruby 知识总结

    在这篇知识总结中,我们将深入探讨Ruby中的线程同步和闭包(包括Blocks、Procs、Lambdas和Methods)。 首先,让我们关注线程同步。在多线程编程中,确保数据安全是非常重要的。Ruby提供了多种机制来实现线程同步,...

    SkBitmapProcState_procs.rar_Before

    标题“SkBitmapProcState_procs.rar_Before”暗示我们即将探讨的是与Skia图形库相关的代码,特别是关于`SkBitmapProcState_procs`的部分。这个标题可能是某个版本或更新前的代码快照,可能用于版本控制或者回溯代码...

    sideband:在单独的边带线程中运行简单的后台作业

    边带 在单独的边带线程中运行简单的作业。 Sideband 可以轻松地将... 要将工作传递给 Sideband,您可以将任何可调用的(procs、lambdas、worker)添加到其队列中: Sideband . queue &lt;&lt; -&gt; { Something . expens

    minigui-procs-dev_2.0.4ubuntu7.10_i386.deb

    基于Ubuntu7.10的minigui开发包

    Find out Stored Procs Which Referenced Specified TableName

    Find out Stored Procs Which Referenced Specified TableName

    SAS-FREQ n’ MEANS.pdf

    Procs FREQ and MEANS have been part of SAS® for over 30 years and are probably some of the most used and loved procedures. They provide useful information directly and as input to other routines and ...

    解决PNP4nagios无法显示进程PROCS图标问题

    下载替换/USR/LOCAL/NAGIOS/LIBEXEC下的check_procs文件,重启服务即可!!

    Procs-开源

    "Procs-开源"是一个专为记录和管理进程而设计的开源项目,旨在支持发票系统的构建。开源软件意味着它的源代码是公开的,允许用户查看、修改和分发,这促进了社区协作和持续改进。在深入探讨这个项目之前,我们需要...

    procs6安装教程

    pro+cs6安装教程+序列号 .

    procs:用Rust编写的ps的现代替代品

    1. **基本用法**:直接运行`procs`将显示所有活动进程的列表。 2. **过滤进程**:可以使用`grep`或正则表达式与其他命令结合,例如`procs | grep nginx`来查找包含“nginx”的进程。 3. **列格式化**:通过`-o`或`--...

    系统介绍计算c语言程序运行时间.rar

    1. **Unix/Linux系统的`clock()`函数**: `clock()`函数返回程序运行时钟周期的总数,单位为`CLOCKS_PER_SEC`,通常表示为秒。例如,我们可以在程序的开始和结束时调用`clock()`,然后通过两者的差值来计算运行时间...

    procs — Rust编写的“ ps”的现代替代品-Rust开发

    procs procs替代了用Rust编写的ps。 文档快速链接功能平台安装使用情况配置功能t procs输出procs替代了用Rust编写的ps。 文档快速链接功能平台安装用法配置功能以彩色和人类可读的格式输出多列上的关键字搜索ps TCP ...

    Ruby on Rails实践之路给PHP和Java开发者的书

    1. **Ruby基础知识**:学习RoR前,了解Ruby的基础语法和特性是必要的,包括元编程、 Blocks、Procs、Lambdas等。 2. **Rails框架结构**:解释RoR的MVC架构,以及每个部分的作用,如Controller负责处理HTTP请求,...

    Python-ProcsKennethReitz尝试提供了一个类似于PythonSubprocess模块功能的高层次抽象API

    1. **简洁的API**:`Procs`库设计了一种更加Pythonic的方式来创建和管理进程。例如,通过简单的函数调用即可启动一个进程,而无需处理复杂的类结构。 2. **流式处理**:`Procs`允许开发者以流的形式处理子进程的...

    ReMESH-2.0_win32

    ReMesh是一个流形三角网格... Falcidieno "ReMESH: An Interactive Environment to Edit and Repair Triangle Meshes" In Procs of Shape Modeling Internationl (SMI'06), IEEE C.S. Press, pp. 271-276, 2006.

    VoIP Demo源码演示

    Currently supports 1 IM and/or 1 voice call at a time. 1 Voice call limitation due to RTC spec. 1 IM call simplifies event handling + need for multiple session windows Simultaneous voice and IM ...

Global site tag (gtag.js) - Google Analytics