当前位置:  开发笔记 > 后端 > 正文

Ruby Code解释道

如何解决《RubyCode解释道》经验,为你挑选了2个好方法。

有人可以解释这段Ruby代码:

def add_spec_path_to(args) # :nodoc:
  args << {} unless Hash === args.last
  args.last[:spec_path] ||= caller(0)[2]
end

我已经看到<<运算符用于连接字符串或用作其他语言的按位运算符,但有人可以在此上下文中解释它.它是以某种方式将空白的lamda附加到args上还是我完全错了?

我也可以看到它像这样使用:

before_parts(*args) << block

Hash关键字吗?

我也不确定||=操作员在说什么.

我在黑暗中同样如此caller(0)[2].



1> Sophie Alper..:

我认为那args是一个Array.

Hash是类的名称 - 第一行将空哈希{}推送到args 除非最后一个元素args已经是Hash(===类的运算符测试对象是否属于某个类).

||=操作类似于+=运营商:这是或多或少相当于:

args.last[:spec_path] = args.last[:spec_path] || caller(0)[2]

因此,它将设置args.last[:spec_path]当且仅当前未设置.

caller方法返回有关调用方法的信息.



2> Mike Woodhou..:

|| =是一种常见的Ruby习语:它仅在尚未设置时才分配值.效果和代码一样

if some_variable == nil
   some_variable = some_value
end

要么

some_variable= some_value unless some_variable

===,当没有被覆盖时,比较两个对象的身份.在这种情况下Hash === args.last,Hash(它是Class类型的对象)正在检查它是否与args数组中最后一项的类匹配.代码利用了一个明显的事实,即Class#===的实现强制检查比较对象的类.

它没有相反的方式,例如:

a = [{}]
Hash === a.last #=> true
a.last === Hash #=> false

方法的尾随参数可以作为哈希的内容提供,而无需提供{}

所以你可以这样做:

def hello(arg1, arg2, arg3)
  puts [arg1.class, arg2.class, arg3.class].join(',')
end

hello 1,2,3 #=> Fixnum,Fixnum,Fixnum
hello :a, "b", :c => 1, :d => 99 #=> Symbol,String,Hash

它通常用于为函数提供可变参数的可变参数列表.

你确定你准确地转录了原始代码吗,顺便问一下?为了获得一个参数数组,你通常会在声明的参数中添加一个*,否则args必须作为一个数组输入,而不是打败对象.

def add_spec_path_to(*args)              # now args is an array
    args << {} unless Hash === args.last # if trailing arguments cannot be
                                         # interpreted as a Hash, add an empty 
                                         # Hash here so that following code will 
                                         # not fail
    args.last[:spec_path] ||= caller(0)[2] # Set the spec_path option if it's not
                                         # already set
end

编辑:进一步扩展*args的事情,试试这个:

def x(*args)
  puts args.join(',')
  puts args.map{|a| a.class }.join(',')
end

x 1,2,:a=>5,:b=>6 
1,2,a5b6
Fixnum,Fixnum,Hash

...使用*args会导致args作为数组呈现给方法.如果我不使用*,就像这样,例如:

def y(args)
  puts args.join(',')
  puts args.map{|a| a.class }.join(',')
end

...然后在我调用方法之前args必须是一个数组,否则我会得到一个"ArgumentError:错误的参数数量",除了一件事情.所以它必须如下所示:

y [1,2,{:c=>3,:d=>4}]

...使用{}显式创建的Hash.它很难看.

所有上述测试均采用MRI 1.8.6,顺便说一句.

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有