简体   繁体   English

Rails语法错误:参数数量错误

[英]rails syntax error: wrong number of arguments

while building a website with rails, I found a little syntax error that I really don't understand what caused it. 在构建带有Rails的网站时,我发现了一个语法错误,我真的不明白是什么原因造成的。

 class User < ApplicationRecord
   has_secure_password
   has_many :posts, dependent: :nullify
   has_many :comments, dependent: :nullify

   validates :first_name, :last_name, presence: true, length: {maximum: 30}
   validates :email, presence: true, uniqueness: true, format: /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i


   def full_name
     (first_name +" "+ last_name).titleize
   end

 end

this is model file for user. 这是用户的模型文件。 If I run this file, it causes an error: wrong number of arguments(given 1, expected 0). 如果我运行此文件,它将导致错误:参数数量错误(给定1,预期为0)。 However if I give a space like so, 但是,如果我给这样的空间,

  def full_name
     (first_name + " "+ last_name).titleize
   end

It runs normally. 它正常运行。

Although I know I can just ignore it, I'm just so curious about how the space causes argument error, it ain't no argument I think.. 尽管我知道我可以忽略它,但我对空间如何导致参数错误感到非常好奇,但我认为它并不是没有参数。

I also ran the same code in normal ruby by making my own titleize method in string class, it works fine without the space. 我还通过在字符串类中创建自己的titleize方法在正常的ruby中运行了相同的代码,它在没有空格的情况下可以正常工作。 so curious ! 好好奇!

You can use ruby_parser to eliminate your doubts about how this is actually parsed. 您可以使用ruby_parser消除对如何实际解析的怀疑。

RubyParser.for_current_ruby.parse '(first_name +" "+ last_name)' results in: RubyParser.for_current_ruby.parse '(first_name +" "+ last_name)'结果为:

s(:call, nil,
         :first_name,
         s(:call, s(:call, s(:str, " "),
                           :+@),
                  :+,
                  s(:call, nil,
                           :last_name)))

Effectively, you're getting first_name((+" ") + last_name) , or in a more redundant/methody fashion, self.first_name((" ".+@).+(self.last_name)) . 有效地,您将获得first_name((+" ") + last_name) ,或者以更冗余/方法的方式获得self.first_name((" ".+@).+(self.last_name))

Meaning there is an argument in a call of the first_name method, stemming from accidental use of +@ , the unary plus, on " " . 意味着在first_name方法的调用中存在一个参数,这是由于意外地在" "上使用一元加号+@引起的。 But since first_name is an attribute getter (I guess?) and does not accept any arguments, you're getting an ArgumentError . 但是由于first_name是一个属性获取器(我猜是吗?)并且不接受任何参数,因此您会收到ArgumentError


To help you interpret this output, a :call S-expression consists of: 为了帮助您解释此输出, :call S-expression包含:

  • :call
  • subject (a value on which a method is being called, nil if self ) 主题(在其上调用方法的值,如果为self ,则为nil
  • method name as a symbol 方法名称作为符号
  • 0 or more arguments 0个或更多参数

And by the way, Rubocop could have warned you about this: 顺便提一下, Rubocop可能已经警告过您:

Lint/AmbiguousOperator: Ambiguous positive number operator. Parenthesize the method
arguments if it's surely a positive number operator, or add a whitespace to the
right of the + if it should be a addition.
(first_name +" "+ last_name)
            ^

Consider adding it into your workflow. 考虑将其添加到您的工作流程中。

This is likely going between the unary-plus operator and the binary-plus operator when you put code directly next to it. 当您将代码直接放在一进制加运算符和二进制加运算符之间时,这很可能会发生。

unary plus is just like unary-minus eg -2 and I'm sure you understand the difference between writing 1 -2 and 1 - 2 ? 一元加号就像一元减号,例如-2 ,我确定您了解写1 -21 - 2之间的区别吗?

As an aside, the standard "ruby way" would be to interpolate rather than use concatenation, so your line would be better written: 顺便说一句,标准的“ ruby​​ way”将是插值而不是使用串联,因此您的行将更好地编写为:

"#{first_name} #{last_name}".titleize

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM