我在RailsCast中找到了以下代码:

def tag_names@tag_names || tags.map(&:name).join(' ')
end

什么是(&:name)map(&:name)是什么意思?


#1楼

它是tags.map { |tag| tag.name }.join(' ')的简写。 tags.map { |tag| tag.name }.join(' ')


#2楼

相当于

def tag_names@tag_names || tags.map { |tag| tag.name }.join(' ')
end

#3楼

这是tags.map(&:name.to_proc).join(' ')的简写

如果foo是具有to_proc方法的对象,则可以将其作为&foo传递给方法,该方法将调用foo.to_proc并将其用作方法的块。

Symbol#to_proc方法最初是由ActiveSupport添加的,但已集成到Ruby 1.8.7中。 这是它的实现:

class Symboldef to_procProc.new do |obj, *args|obj.send self, *argsendend
end

#4楼

同时让我们注意到,&符#to_proc魔术可以与任何类一起使用,而不仅限于Symbol。 许多Ruby #to_proc选择在Array类上定义#to_proc

class Arraydef to_procproc { |receiver| receiver.send *self }end
end# And then...[ 'Hello', 'Goodbye' ].map &[ :+, ' world!' ]
#=> ["Hello world!", "Goodbye world!"]

&通过在其操作数上发送to_proc消息来工作,在上面的代码中,该操作数属于Array类。 并且由于我在Array上定义了#to_proc方法,因此该行变为:

[ 'Hello', 'Goodbye' ].map { |receiver| receiver.send( :+, ' world!' ) }

#5楼

Josh Lee的答案几乎是正确的,只是等效的Ruby代码应如下所示。

class Symboldef to_procProc.new do |receiver|receiver.send selfendend
end

class Symboldef to_procProc.new do |obj, *args|obj.send self, *argsendend
end

使用此代码,当执行print [[1,'a'],[2,'b'],[3,'c']].map(&:first) ,Ruby将拆分第一个输入[1,'a']分为1,而'a'则赋予obj 1,而args* 'a'则引起错误,因为Fixnum对象1没有方法self(即:first)。


执行[[1,'a'],[2,'b'],[3,'c']].map(&:first) ;

  1. :first是一个Symbol对象,因此当将&:first作为参数提供给map方法时,将调用Symbol#to_proc。

  2. map通过参数[1,'a']向:first.to_proc发送呼叫消息,例如,执行:first.to_proc.call([1,'a'])

  3. Symbol类中的to_proc过程将发送消息发送到带有参数(:first)的数组对象( [1,'a'] ),例如,执行[1,'a'].send(:first)

  4. 迭代[[1,'a'],[2,'b'],[3,'c']]对象中的其余元素。

这与执行[[1,'a'],[2,'b'],[3,'c']].map(|e| e.first)表达式相同。


#6楼

这里发生了两件事,理解这两者很重要。

如其他答案中所述,正在调用Symbol#to_proc方法。

但是之所以在符号上调用to_proc的原因是因为它被作为块参数传递给map 。 将&放在方法调用中的参数前面会导致这种方式传递。 这适用于任何Ruby方法,而不仅仅是带有符号的map

def some_method(*args, &block)puts "args: #{args.inspect}"puts "block: #{block.inspect}"
endsome_method(:whatever)
# args: [:whatever]
# block: nilsome_method(&:whatever)
# args: []
# block: #<Proc:0x007fd23d010da8>some_method(&"whatever")
# TypeError: wrong argument type String (expected Proc)
# (String doesn't respond to #to_proc)

Symbol被转换为Proc因为它已作为块传递。 我们可以尝试通过将proc传递给.map而不使用&符的方式来证明这一点:

arr = %w(apple banana)
reverse_upcase = proc { |i| i.reverse.upcase }
reverse_upcase.is_a?(Proc)
=> truearr.map(reverse_upcase)
# ArgumentError: wrong number of arguments (1 for 0)
# (map expects 0 positional arguments and one block argument)arr.map(&reverse_upcase)
=> ["ELPPA", "ANANAB"]

即使不需要转换,该方法也不知道如何使用它,因为它需要一个块参数。 用&传递给.map它期望的块。


#7楼

如下:

def tag_namesif @tag_names@tag_nameselsetags.map{ |t| t.name }.join(' ')
end

#8楼

在这里:name是指向标记对象的方法name的符号。 当我们将&:name传递给map ,它将把name视为proc对象。 简而言之, tags.map(&:name)作用是:

tags.map do |tag|tag.name
end

#9楼

(&:name)是(&:name.to_proc)的缩写,它与tags.map{ |t| t.name }.join(' ') tags.map{ |t| t.name }.join(' ')

to_proc实际上是用C实现的


#10楼

tags.map(&:name)

是相同的

tags.map{|tag| tag.name}

&:name仅使用符号作为要调用的方法名称。


#11楼

它的意思是

array.each(&:to_sym.to_proc)

#12楼

尽管我们已经有了不错的答案,但是从初学者的角度来看,我想添加其他信息:

map(&:name)在Ruby中是什么意思?

这意味着,您要将另一个方法作为参数传递给map函数。 (实际上,您传递的是一个已转换为proc的符号。但这在这种情况下并不重要)。

重要的是,您有一个名为namemethod ,该方法将由map方法用作参数而不是传统的block样式。


#13楼

map(&:name)接受一个可枚举的对象(在您的情况下为标签)并为每个元素/标签运行name方法,并从该方法输出每个返回的值。

这是

array.map { |element| element.name }

它返回元素(标签)名称的数组


#14楼

它基本上在数组中的每个标签上执行方法调用tag.name

这是简化的红宝石速记。


#15楼

许多人不知道的另一个很酷的速记是

array.each(&method(:foo))

这是的简写

array.each { |element| foo(element) }

通过调用method(:foo)我们从self中获取了一个Method对象,该对象代表其foo方法,并使用&表示它具有to_proc 方法 ,该方法将其转换为Proc

当您想做无指向性的样式时,这非常有用。 一个示例是检查数组中是否有任何与字符串"foo"相等的字符串。 有常规方法:

["bar", "baz", "foo"].any? { |str| str == "foo" }

还有一种无意义的方式:

["bar", "baz", "foo"].any?(&"foo".method(:==))

首选方式应该是最易读的方式。

map(&:name)在Ruby中是什么意思?相关推荐

  1. ruby 中 map方法

    ruby 中 map方法 对数组中每个元素进行表达式操作,原始数组不会被改变,返回执行表达式结果的新数组 # 把 numbers 中每个值映射到 String 的 Array numbers = [1 ...

  2. 为什么在Ruby中使用`rescue Exception =gt; e`样式不好?

    本文翻译自:Why is it bad style to `rescue Exception => e` in Ruby? Ryan Davis's Ruby QuickRef says (wi ...

  3. 在Ruby中,如何跳过.each循环中的循环,类似于‘continue‘[duplicate]

    本文翻译自:In Ruby, how do I skip a loop in a .each loop, similar to 'continue' [duplicate] This question ...

  4. ruby中的符号_Ruby中的凡人和不朽符号

    ruby中的符号 In this article, we're going to explore the following topics: 在本文中,我们将探讨以下主题: symbols are u ...

  5. ruby 数组自定义排序_在Ruby中对数组排序

    ruby 数组自定义排序 Sorting was a preoccupation for computer scientists from early on. There were many algo ...

  6. 如何在Ruby中使用数组方法

    介绍 (Introduction) Arrays let you represent lists of data in your programs. Once you have data in an ...

  7. Ruby中的设计模式

    继续 上 节讲述过的Singleton . Proxy 及 Iterator各模式,本节再来考察几个别的设计模式.下面按顺序来考察 Prototype . Template Method 和 Obse ...

  8. Ruby中的设计模式——《松本行弘的程序世界》

    < 设计模式 > 一书是用C++ 和 Smalltalk 介绍模式实例的.看了那些例子,大家都会感觉到,绝大多数的模式用 Smalltalk 实现起来非常简单.这是为什么呢? 因为Smal ...

  9. Ruby中爬虫的实现

    2019独角兽企业重金招聘Python工程师标准>>> Ruby中实现网页抓取,一般用的是mechanize,使用非常简单. 安装 sudo gem install mechaniz ...

最新文章

  1. ​【安全牛学习笔记】WPS及其他工具WPS
  2. JDK自带线程池介绍及使用环境
  3. Blazor University (4)组件 — 单向绑定
  4. java 三元 代替 if_Java 中三元和 if else 哪个的效率比较高,有底层解释吗,谢谢了!...
  5. Windows编程之网络之邮件槽通讯
  6. Ant Design Tabs标签页隐藏的标签内元素无法获取到
  7. 探讨 | 深入探讨Redis管道
  8. 【运维技术】数据库主从同步搭建
  9. 20160507-hibernate入门
  10. 【GYM-100889 D】Dicy Numbers【数学推导求解】
  11. 写作技巧~100段作文排比句(81-100段),考试一定用得上,赶紧收藏!
  12. php做seo优化,php做seo优化能力有哪些
  13. Leetcode PHP题解D1:宝石与石头
  14. ionic3硬件检测、请求权限插件 Diagnostic 的用法
  15. 【微信云开发】简记操作:删除云开发环境
  16. windows版微信多开
  17. 【初赛】计算机操作系统
  18. 华为Android岗面经;群面+技术面+英语面+面试题详解
  19. 机房动力环境监控系统
  20. 最牛散户最新版唐亮一年获利超3亿

热门文章

  1. 3D图形学的线性代数的通俗解释。
  2. Android之linux基础教学之一 内存地址
  3. 算法-------三角形最小路径和(Java版本)
  4. Glide 源码分析与面试提问
  5. 转载:vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  6. 第十、十一周项目四 - 教师兼干部类
  7. 第八周项目二-用对象数组操作长方柱类
  8. Android10.0系统启动之Launcher(桌面)启动流程-[Android取经之路]
  9. wireshark网络分析就这么简单_【读书笔记】2wireshark网络分析就这么简单——不同子网如何发送消息。...
  10. wsl2 图形界面_WSL2配置xrdp一键启动至桌面环境