Ruby 从`object.method`字符串发送方法

Ruby 从`object.method`字符串发送方法,ruby,Ruby,我想在一个块中对来自不同来源的数据运行相同的进程。从中获取要搜索的元素的方法具有不同的名称。这是我想做的一个例子: def search_in(list, i) send(list) { |s| puts s if s.include?(i) } end 那么我想这样称呼它: search\u in(“contents.each”,i)或search\u in(“@things.entries”,i)send只向接收者发送一条消息(方法调用)。您将接收器指定为字符串的一部分,这意味着您必须

我想在一个块中对来自不同来源的数据运行相同的进程。从中获取要搜索的元素的方法具有不同的名称。这是我想做的一个例子:

def search_in(list, i)
  send(list) { |s| puts s if s.include?(i) }
end
那么我想这样称呼它:


search\u in(“contents.each”,i)
search\u in(“@things.entries”,i)
send
只向接收者发送一条消息(方法调用)。您将接收器指定为字符串的一部分,这意味着您必须执行一些向导才能正确提取它。不过,您可能正在做一些不应该在这里做的事情——我鼓励您详细说明您的问题,以获取有关如何重构它以避免此特定操作的建议

但是,要解决这个问题,您需要提取并解析接收方,提取消息,然后将消息发送给接收方。你可能应该避免评估

给定一个字符串,
list

# Split the string into something that should resolve to the receiver, and the method to send
receiver_str, method = list.split(".", 2)

# Look up possible receivers by looking in instance_methods and instance_variables.
# Note that this isn't doing any constant resolution or anything; the assumption
# is that the receiver is visible in the current scope.
if instance_methods.include?(receiver_str)
  receiver = send(receiver_str)
elsif instance_variables.include?(receiver_str)
  receiver = instance_variable_get(receiver_str)
else
  raise "Bad receiver: #{receiver_str}"
end

receiver.send(method) {|s| ... }
但考虑到这是一个静态块,您希望传递一个可枚举的;与其将要解析的字符串传递给接收方和方法,不如尝试传递可枚举项本身:

def search_enumerable_for(enum, i)
  enum.each {|e| puts e if e.include?(i) }
end

search_enumerable_for(contents, value)
search_enumerable_for(@things.entries, value)

你的问题是什么?为什么你当前的解决方案不起作用?@sawa我不知道如何实现这一点,因为send不允许在其参数中输入目标对象的名称。谢谢你的解释,克里斯。事实上,我正在制作一个播放列表管理器,我想有两个功能:向播放列表中添加歌曲和从播放列表中删除歌曲。它将在参数中使用歌曲标题,但我的添加和删除代码非常相似(有一个菜单来处理多个匹配等),除了两个元素。特别是,它在删除时在播放列表中搜索匹配项,在添加时在整个歌曲数据库中搜索匹配项,将它们放入一个数组中。因此,我想通过创建一个函数来避免代码重复,该函数在给定上下文的情况下调用不同,因为每个函数都有40行长。在这种情况下,只需让您的方法接受包含歌曲列表的对象并对其执行操作,而不是在代码中引用对象的字符串。