`

Proc、Block的区别与使用

    博客分类:
  • Ruby
 
阅读更多

  代码块,我的理解就是匿名方法,有点像Java中的匿名类一样,似乎用更贴切的说法叫闭包,一个我至今未接触过的东西。学习到代码块和代码块对象(Proc)的时候,看着很晕,一个代码块对象可以用lambda和->同时定义,与对代码块的错误理解纠结在一起,晕了一晚上。今天早上又找了些资料看看,最终才弄懂。写这篇文章的时候,使用的Ruby是1.9.2

 

  Block和Proc的区别就是Proc是Block Object,需要用call方法调用,而Block则不用。

 

1.  代码块的定义分为两种方式调用,一种是do end定义,适用于多行代码,一种是{}定义,适用于一行,两者没有优劣,只有习惯的不同,遵从这种文化吧。

    下面这个就是最简单的代码块示例:

 

5.times do |i|
  puts "No.#{i+1}"
end

 

   但是,如果你想在一个方法调用一个外部的代码块,如何做到呢?这个magic可以通过yield关键字来做到

 

 

def bye(name)
  puts "bye,#{name}"
  if block_given?
    yield
  end
end

bye("Steve Jobs"){puts "missing you "}

    代码块可以作为一个隐含参数,并且是最后一个,而且只能使用一个,来传递给别的方法,前面正常的参数要用括号起。像这个例子,我传递了一个打印“missing you”的代码块给方法bye,通过block_given?来判断是否传递了一个代码块过来,传过来的话,则用yield执行,如果不判断,而直接使用yield的时候,没传代码块是要报错的。其输出结果为:

bye,Steve Jobs
missing you 

 

2.Proc的使用

   Proc就是代码块对象,既然是对象,一旦定义,就可以多次使用了,Proc当然可以用new来创建,这个似乎并不常用,常用的倒是用lambda方法和符号->来定义

2.1 lambda方式

    在方法名lambda后面加上代码块即可,示例如下:

 

proc=lambda {|name| puts "hello,#{name}"}
proc.call 'theoffspring'
proc.call 'Mike'

  输出结果是:

hello,theoffspring
hello,Mike

   而且,作为对象,它可以作用参数传递给方法调用,个数不限,位置不限,这点克服了代码块来作为参数传递的局限性,如:

 

def test_proc_multi_params(name, proc, proc2)
  puts "#{name} is coming ,and he wants to..."
  proc.call
  proc2.call
end

test_proc_multi_params("the offspring", lambda { puts "eat potato" }, lambda { puts "and water melon" })

  输出结果:

the offspring is coming ,and he wants to...
eat potato
and water melon 

   不过 ,代码块可以通过在参数名前加个&来转换成代码块对象,但仍然只能有一个,且在方法参数列表的最后,如:

 

def test_converted_block(name,&action)
  puts "#{name} is "
  action.call
end

test_converted_block("the offspring") {puts "eating lunch"}

 

  输出:

the offspring is
eating lunch 

注意调用   test_converted_block的参数写法,挺特殊的,不得不承认

 

2.2 ->方式

   你只要把lambda出现的地方换成->就行了,哦,对了,这种方式在定义Proc参数的时候,要写到括号的外面,多个的话,以逗号分隔。

    如:

 

proc=-> name { puts "hello,#{name}" }
proc.call 'theoffspring'
proc.call 'Mike'
分享到:
评论

相关推荐

    Ruby中的block、proc、lambda区别总结

    在规则引擎中,Ruby 的闭包使用特别频繁,而且有 block,Proc和 lambda 等后几种形式的用法,很让人困惑。为了深入理解代码,再次认真学习了一下 Ruby 的闭包,特别是 block,proc 和 lambda 几种用法的异同,这次的...

    Ruby中的Proc类及Proc的类方法Proc.new的使用解析

    Ruby中的Proc类是用于封装代码块(block)的对象,它允许你像操作对象一样操作代码。Proc类提供了创建和管理代码块的能力,特别是在需要在不同的上下文中调用或传递代码块时非常有用。 Proc可以通过`Proc.new`类...

    hello_proc.tar.gz_device_create_file_proc_hello

    标签"device_create_file"和"proc_hello"进一步明确了我们讨论的主题:创建设备文件,并通过/proc/hello与内核模块交互。这可以帮助开发者学习如何扩展Linux内核,以支持自定义设备或模拟硬件。 总的来说,通过proc...

    Ruby中使用Block、Proc、lambda实现闭包

    Ruby中的闭包实现有:Block,Proc,Lambada。 首先,我们来看Block。 代码如下: ary = [1,2,3,4] ary.collect! do |a|  a*a end ary.each do |a|  puts a end 这段代码,我们使用了Array对象的block方法,将ary中...

    ruby基础教程(第四版)第21章 Proc类1

    理解Proc和`lambda`的区别以及如何使用它们是Ruby编程中的重要概念,这有助于编写更灵活和可维护的代码。Proc对象和闭包的特性使得我们能够在函数式编程中利用高阶函数,以及在处理回调、事件驱动编程等方面发挥重要...

    proc observer

    此外,`/proc/<pid>/status`文件会显示特定进程的内存使用情况,包括VIRT(虚拟内存)、RES(驻留内存)和SHR(共享内存)等。 ### 磁盘调用信息 Linux的磁盘I/O信息主要在`/proc/diskstats`文件中体现。这个文件...

    前端开源库-gobem-proc-uglify

    在实际应用中,`gobem-proc-uglify`与其他前端构建工具(如Webpack、Gulp、Grunt等)配合使用,可以构建出更加高效的前端项目。例如,结合使用Babel进行ES6+代码转换,使项目兼容更多浏览器;或者配合PostCSS处理CSS...

    ide-floppy_proc.rar_capacity

    标题中的"ide-floppy_proc.rar_capacity"暗示了我们正在探讨Linux内核中与IDE(集成设备电子)软驱容量显示相关的源代码。在Linux操作系统中,IDE接口不仅用于硬盘,也用于软盘驱动器(Floppy Disk Drive,FDD)。`...

    block_dev_driver.rar_block device driver_块设备驱动

    1. **块设备与字符设备的区别** - 块设备:数据读写以固定大小的块为单位,如硬盘、SSD等,通常有缓冲区管理。 - 字符设备:数据传输逐字符进行,无固定块大小,如键盘、串口等。 2. **块设备驱动的结构** - `...

    深入理解Ruby中的代码块block特性

    本文深入探讨了Ruby中的代码块(block)特性,从Block的基础定义出发,介绍了其与Lambda的关系、作为方法参数的应用、`yield`关键字的使用、Block与方法之间的转换,以及Block作为对象的本质。通过这些知识点的学习...

    procfs:procfs提供了从伪文件系统proc检索系统,内核和进程指标的功能

    某些子软件包(例如blockdevice )需要访问proc和sys文件系统。 fs , err := blockdevice . NewFS ( "/proc" , "/sys" ) stats , err := fs . ProcDiskstats () 包装组织 该项目中的软件包是根据(1)数据

    深入讲解Ruby中Block代码快的用法

    Block通常与诸如 `each`, `map`, `select` 等数组方法一起使用来简化代码并提高可读性。 #### Block作为参数 Block可以在方法中作为参数传递。如果一个方法的最后一个参数前带有 `&` 符号,这意味着方法期望接收一...

    详解Ruby中的代码块对象Proc

    正确理解和区分代码块与Proc对象之间的关系是避免这类问题的关键。 在编写代码时,应尽量避免显式创建Proc对象,除非确实需要。当处理代码块和Proc对象时,保持清晰的思维并确保正确使用`&`操作符,可以避免许多...

    multi_block:将多个块传递给 Ruby 方法

    多块 MultiBlock 是一个迷你框架,用于将多个块传递给方法。 它使用以简单的语法完成此操作。 接收方法可以产生所有块...yield :success # calls :success proc without args yield :success , "Code Brawl!" # calls

    sysfs文件系统详解IBM

    sysfs 文件系统的目录结构也非常重要,/sys 目录是 sysfs 文件系统的根目录,下面包含了多个子目录,例如 block, bus, class, dev, devices, firmware, fs, kernel, module, power 等。每个子目录都包含了特定的设备...

    SAS系统讲义-条形图、圆饼图和星形图.doc

    PROC GCHART语句需要指定数据集,并可以跟随着多个图形要求语句,如VBAR、HBAR、BLOCK、PIE和STAR。每个图形要求语句可以有自己的通用选项列表和专用选项列表。通用选项适用于所有图形,而专用选项特定于每个图形...

    Linux读取U盘或者移动硬盘序列号并获取U盘或者移动硬盘分区名

    这个数字与前面 /proc/scsi/usb-storage目录中的相对应,子目录表示sata硬盘。比如 /sys/class/scsi_device/2:0:0:0/device/block 中有USB设备,从该目录下得到U盘或者移动硬盘的分区名,比如sda1。 该demo实现了...

    透视Ruby 1.9的Lambda函数

    Lambda与Block相似,但有一些重要的区别,例如Lambda在处理参数数量不匹配时会抛出异常,而Block则会尝试适应。此外,Lambda对return操作的处理也有所不同,它会返回到调用Lambda的地方,而Block则会返回到Block所在...

    编译原理课程设计,实现简单的类C语言编译器,包括词法分析、语法分析、语义分析、翻译与简单优化.zip

    本次课程设计中基本完成了相关内容,包括词法分析、语法分析、语义分析、翻译、解释设备与应用界面pl0简介(BNF描述)<prog> → program <id><block><block> → [<proc>]<body><condecl> → const <const>{,<const>}...

Global site tag (gtag.js) - Google Analytics