Ruby `地图';:为字符串调用的私有方法(NoMethodError)

Ruby `地图';:为字符串调用的私有方法(NoMethodError),ruby,Ruby,我尝试编写一个私有函数,该函数将接收单个令牌并返回给定的令牌,而不使用空格或标点符号,例如: normalize_token(" cat.") # => "cat" 然后我定义了一个包含标点和空格的标记数组: ["a.", " b...."] 我想用我定义的函数来映射它。我希望返回一个新对象,如下所示: ["a", "b"] 下面是一小段代码: private def normalize_token(token) token.gsub(/\W/, ' ') # does

我尝试编写一个私有函数,该函数将接收单个令牌并返回给定的令牌,而不使用空格或标点符号,例如:

normalize_token(" cat.")
# => "cat"
然后我定义了一个包含标点和空格的标记数组:

["a.", "      b...."]
我想用我定义的函数来映射它。我希望返回一个新对象,如下所示:

["a", "b"]
下面是一小段代码:

private def normalize_token(token)
  token.gsub(/\W/, ' ') # does the same thing as [^A-Za-z0-9_]
end

["a.", "      b...."].map!(&:normalize_token)
我得到:

map!':私有方法
normalize_token'为“a.”调用:字符串 (命名者)


非常感谢您对我所做错误的任何帮助或解释。

不要传递方法引用,而是传递一个块:

private def normalize_token(token)
  token.gsub(/\W/, ' ') # does the same thing as [^A-Za-z0-9_]
end

["a.", "      b...."].map! {|token| normalize_token token}
这将在字符串中留下空白,因此您可能希望
chomp它们或将您的
gsub
更改为
gsub(/\w/,'')

解释

第一个问题是
normalize\u令牌
是私有的。你可以通过公开它或者通过@alex提到的
send
ing来规避这个问题

然而,第二个问题更加微妙

通过传递方法引用,您基本上具有以下内容

["a.", "      b...."].map! {|token| token.send :normalize_token }
运行此操作将导致以下错误消息:

ArgumentError (wrong number of arguments (given 0, expected 1))

地图
不会将映射值作为参数传递给
normalize_token
。(请注意,
send
将您的映射值作为接收方,而不是作为参数。)相反,通过使用声明了变量的块,我们可以通过在块中显式地将映射值作为参数传递来绕过这一问题。

关于
&:
的快速说明-它完成了与
{i}相同的事情
通过使用&to调用:对象上的\u proc,然后将其作为块传递给方法-因此为了使用它,需要在传递给
映射的任何对象上定义
&:
后面的内容

下面是一个示例,打开
String
类在那里定义它:

class String
  def normalize_token
    self.gsub(/\W/, ' ')
  end
end
这将允许您使用原始的
[“a.”,“b…”地图!(&:normalize_token)

在现实生活中这样做不是一个好主意,因为您可能希望在负责生成这些字符串的任何类中定义normalize_标记。但这应该会让你开始。

这很有效。你能提供一个小的解释为什么“通过一个块”可以解决这个问题吗?更新了我的答案,有更多的解释。明白。非常感谢你!好的,我想我明白了。谢谢你,亚历克斯!