有人能告诉我以下代码片段的含义吗?
obj.send("#{method_name}")
is和does是什么意思?
有人能告诉我以下代码片段的含义吗?
obj.send("#{method_name}")
is和does是什么意思?
send
方法会向一个对象实例及其在类层次结构中的祖先发送一条消息,直到某个方法响应该消息(因为它的名字与第一个参数匹配)。
实际上,这两行代码是等价的:
1.send '+', 2
1.+(2)
1 + 2
请注意,send
方法可以绕过可见性检查,这意味着您也可以调用私有方法(对单元测试很有用)。
send
之前确实没有变量,那就意味着全局对象被使用了。send :to_s # "main"
send :class # Object
send 是 Ruby 中的一个方法,可以通过指定方法名和对应参数来调用另一个方法。
class Klass
def hello(*args)
"Hello " + args.join(' ')
end
end
k = Klass.new
k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
我认为 .send 方法中最有用的功能之一是它可以动态调用方法。这可以节省很多输入。 .send 方法最常见的用法之一是动态分配属性。例如:
class Car
attr_accessor :make, :model, :year
end
要定期分配属性,需要
c = Car.new
c.make="Honda"
c.model="CRV"
c.year="2014"
使用.send方法也可以:c.send("make=", "Honda")
c.send("model=", "CRV")
c.send("year=","2014")
但是所有这些都可以用以下方式替换:
假设您的Rails应用程序需要将用户输入的属性分配给您的car类,您可以执行以下操作
c = Car.new()
params.each do |key, value|
c.send("#{key}=", value)
end
send
时,我总是会rescue NoMethodError
,并将错误发送到日志和/或实现一些默认行为,以应对未定义方法的情况。 - Matthew另一个类似于Antonio Jha的例子:https://dev59.com/oXA75IYBdhLWcg3wW3u8#26193804
如果你需要读取对象的属性,则可以使用类似的方法。
例如,如果你有一个字符串数组,如果尝试通过迭代并调用它们的对象来处理它们,那么这将不起作用。
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.a
end
# => NoMethodError: undefined method `a'
然而,您可以将字符串send
到对象:
atts = ['name', 'description']
@project = Project.first
atts.each do |a|
puts @project.send(a)
end
# => Vandalay Project
# => A very important project
define_method
时,它也可能会有所帮助:https://apidock.com/ruby/Module/define_method。 - Mike Vallanosend
是另一种“调用方法”的方式。例如:
o = Object.new
o.to_s # => "#<Object:0x00005614d7a24fa3>"
# is equivalent to:
o.send(:to_s) # => "#<Object:0x00005614d7a24fa3>"
这种方法的好处是,您可以将要调用的方法作为参数传递。以下是一个简单的示例:
def dynamically_call_a_method(method_name)
o = Object.new
o.send method_name
end
dynamically_call_a_method(:to_s) # => "#<Object:0x00005614d7a24fa3>"
您可以传入您想要调用的方法。在这种情况下,我们传入了:to_s
。当进行Ruby元编程时,这非常方便,因为它允许我们根据不同的要求调用不同的方法。
发送还可以用作展示 Ruby 中所有内容都是对象的方式
1.send(:+, 1) ## -> 2
3.send(:*, 2) ## -> 6
视图的另一个使用案例:
<%= link_to
send("first_part_of_path_#{some_dynamic_parameters}_end_path",
attr1, attr2), ....
%>
允许您编写可扩展的视图,可与各种对象一起使用:
render 'your_view_path', object: "my_object"
我对这个话题来说有点晚了。作为一个新手,我只是使用它,并希望对像我一样想要直接的答案的人有所帮助。 filter_hash.each{|k,v| order_additional_hash[send(method_name, k)] = v}
如上所示,send(method_name)是我们想要调用的方法。如果方法名作为字符串传递给参数并且k是我们想要传递给方法的参数,则匹配名称并调用该方法。