我尝试编写一个私有函数,它将接受一个令牌并返回给定的令牌而没有空格或标点符号,例如:
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!': private method
normalize_token'呼吁" a。":字符串 (NoMethodError)
我将非常感谢您对我做错的任何帮助甚至解释。
答案 0 :(得分:2)
不是传递方法引用,而是传递一个块:
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_token
是私有的。您可以通过公开或send
将其作为@alex提及来解决这个问题。
然而,第二个问题更为微妙。
通过传递方法参考,您基本上有以下
["a.", " b...."].map! {|token| token.send :normalize_token }
运行此命令将导致以下错误消息:
ArgumentError (wrong number of arguments (given 0, expected 1))
map!
不会将映射值作为参数传递给normalize_token
。 (请注意send
将您的映射值作为接收器而不是参数。)相反,通过使用带有声明变量的块,我们可以通过在块中显式传递映射值作为参数来解决这个问题。
答案 1 :(得分:1)
关于&:
的快速说明 - 它通过使用&amp;成就与{|i| ...}
完成相同的事情。在:object上调用to_proc,然后将其作为块传递给方法 - 因此为了使用它,需要在传递给&:
的任何对象上定义map!
后面的任何内容。< / p>
这是一个例子,打开String
类来定义它:
class String
def normalize_token
self.gsub(/\W/, ' ')
end
end
这将允许您使用原始["a.", " b...."].map!(&:normalize_token)
。
在现实生活中做这样的事情并不是一个好主意,因为你可能希望在任何负责生成这些字符串的类中定义normalize_token。但它应该让你开始。