简体   繁体   English

`map!':调用String的私有方法(NoMethodError)

[英]`map!': private method called for String (NoMethodError)

I tried to write a private function that will take in a single token and return the given token without white space or punctuation, for example: 我试图编写一个私有函数,该函数将接受单个令牌并返回给定的令牌,而没有空格或标点符号,例如:

normalize_token(" cat.")
# => "cat"

I then defined an array of tokens that have punctuation and white space: 然后,我定义了具有标点符号和空格的令牌数组:

["a.", "      b...."]

which I'd like to map over using my defined function. 我想使用定义的函数进行映射。 I expect a new object returned, which looks like: 我希望返回一个新对象,如下所示:

["a", "b"]

Here is a small snippet of code: 这是一小段代码:

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

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

I get: 我得到:

map!': private method normalize_token' called for "a.":String (NoMethodError) map!': private method调用“ a”的map!': private method normalize_token':字符串(NoMethodError)

Any help or even an explanation of what I'm doing wrong would be greatly appreciated. 任何帮助或什至是我做错的解释将不胜感激。

Instead of passing the method reference, pass a block: 而不是传递方法引用,而是传递一个块:

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}

This will leave white space in your strings, so you might want to chomp! 这将在字符串中留出空格,因此您可能想要chomp! them or change your gsub to gsub(/\\w/, '') 他们或将您的gsub更改为gsub(/\\w/, '')

Explanation 说明

The first problem is that normalize_token is private. 第一个问题是normalize_token是私有的。 You can get around that by making it public or by send ing it as @alex mentioned. 您可以通过将其公开或按@alex所述send它来解决该问题。

The second problem however is more subtle. 然而,第二个问题更加微妙。

By passing the method reference, you essentially have the following 通过传递方法引用,您基本上具有以下内容

["a.", "      b...."].map! {|token| token.send :normalize_token }

Running this will result in the following error message: 运行此命令将导致以下错误消息:

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

map! will not pass the mapped value to normalize_token as an argument. 不会将映射的值作为参数传递给normalize_token (notice that the send has your mapped value as a receiver but not as an argument .) Instead, by using a block with a variable declared, we can get around this by passing the mapped value as an argument explicitly in the block. (请注意, send将您的映射值作为接收者,但没有作为参数 。)相反,通过使用声明了变量的块,我们可以通过将映射值作为参数明确传递给块来解决此问题。

Quick note on &: - it accomplishes the same thing as {|i| ...} 关于&:简短说明&: -它完成与{|i| ...} {|i| ...} by using & to call to_proc on the :object, then passes it as a block to the method - so in order to use it, whatever follows &: needs to be defined on whatever object is being passed to map! {|i| ...} ,使用&调用:object上的to_proc,然后将其作为一个块传递给该方法-因此,要使用它,需要在传递给map!任何对象上定义&:后面的内容map! .

Here's an example, cracking open the String class to define it there: 这是一个示例,打开String类以在其中定义它:

class String
  def normalize_token
    self.gsub(/\W/, ' ')
  end
end

Which will let you use your original ["a.", " b...."].map!(&:normalize_token) . 它将使您可以使用原始的["a.", " b...."].map!(&:normalize_token) Not a great idea to do stuff like this in real life, since you'd probably want normalize_token to be defined in whatever class is responsible for generating these strings. 在现实生活中做这样的事情不是一个好主意,因为您可能希望在负责生成这些字符串的任何类中定义normalize_token。 But it should get you started. 但这应该可以帮助您入门。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 私有方法“ puts”需要“ string”:String(NoMethodError) - private method `puts' called for “string”:String (NoMethodError) 私有方法,称为noMethodError ruby - private method called noMethodError ruby 私有方法`select'调用了nil:NilClass(NoMethodError) - private method `select' called for nil:NilClass (NoMethodError) 私有方法`split'调用了nil:NilClass(NoMethodError) - private method `split' called for nil:NilClass (NoMethodError) 私有方法'eval'调用了Math:Module(NoMethodError) - private method 'eval' called for Math:Module (NoMethodError) 私有方法“ chomp”调用了nil:NilClass(NoMethodError) - private method `chomp' called for nil:NilClass (NoMethodError) 私有方法`puts'调用nil:NilClass(NoMethodError) - private method `puts' called for nil:NilClass (NoMethodError) 调用Refinery :: Admin :: PagesController:Class的私有方法“ prepend”(NoMethodError) - private method `prepend' called for Refinery::Admin::PagesController:Class (NoMethodError) NoMethodError:为类调用了私有方法“ existence_check” - NoMethodError: private method `existence_check' called for Class Sinatra Activerecord:为Psych:Module调用的私有方法“ load”(NoMethodError) - Sinatra Activerecord: private method `load' called for Psych:Module (NoMethodError)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM