【问题标题】:(ArgumentError) Ruby : wrong number of arguments(ArgumentError) Ruby:参数数量错误
【发布时间】:2021-12-19 09:04:31
【问题描述】:
def visualization (name, age, looks)
  age.to_s
  puts name + ' is ' + age + ' years old and looks ' + looks
end

visualization (name = 'Mary', age = 5, looks = 'bad')

#=> `visualization': wrong number of arguments (given 1, expected 3) (ArgumentError)

【问题讨论】:

  • (1) 删除visualization 和它的参数之间的空格。 (2) age.to_s 不会变异 age。只需在连接期间使用age.to_s 而不是age
  • 你真的在写一个程序来评估幼儿的容貌吗? xd
  • 您能否在问题中添加一些信息?比如,你做了哪些研究来解决问题,你阅读了哪些文档,你理解了文档的哪些部分,哪些没有,为什么研究和文档没有帮助,你做了哪些步骤来调试问题,等等。?这样,您可以避免回答者浪费他们和您的时间来解释您已经知道的事情,和/或您已经研究过但没有帮助您的事情。目前,您似乎只是将一条错误消息转储到文本框中,并希望其他人为您完成工作。
  • 我的名字参数变成数组然后我发送参数可视化(名字='Ann',年龄=2)。 p name.instance_of? String #=> False p name #=> ["Ann", 2] 有人必须给蹒跚学步的孩子打分:-D

标签: ruby arguments


【解决方案1】:

age.to_s 不会改变age 对象(您不能在Ruby 中更改对象的类),它只是返回 一个新字符串。 因此,您要么必须通过 age = age.to_s 重新分配年龄,要么将 to_s 调用移动到需要的位置:

def visualization(name, age, looks)
  puts name + ' is ' + age.to_s + ' years old and looks ' + looks
end

您可以改用字符串插值,这更符合习惯,并且使to_s 调用变得多余:

def visualization(name, age, looks)
  puts "#{name} is #{age} years old and looks #{looks}"
end

调用此方法时,您通过以下方式传递参数:

visualization('Mary', 5, 'cute')
#            ^ and no space here

代码中的分配没有多大意义。你可能想要keyword arguments:(注意冒号)

def visualization(name:, age:, looks:)
  puts "#{name} is #{age} years old and looks #{looks}"
end

visualization(name: 'Mary', age: 5, looks: 'cute')

【讨论】:

    【解决方案2】:

    所以这里的主要问题是visualization 和它的参数之间的空格。当 ruby​​ 看到visualization (name = 'Mary', age = 5, looks = 'bad') 时,它会将“可视化”识别为一种方法(因为它有参数),但它首先会尝试计算括号中的表达式:

    (name = 'Mary', age = 5, looks = 'bad')
    

    这本身就是一个有效的 ruby​​ 表达式,但看到 ruby​​ 是如何解释它的可能会非常令人惊讶:

    name = ('Mary', (age = 5), (looks = 'bad'))
    

    导致name['Mary', 5, 'bad']age5looks 为“坏”。

    由于表达式只是一个赋值,它返回分配的值(数组['Mary', 5, 'bad']),然后将其传递给您的visualisation 方法。由于您传递的是单个数组并且您的方法需要三个参数,因此您会收到错误消息。

    按照每个解决方案,只需删除方法调用及其参数之间的空格。您也不需要命名参数 - 这不是 Python - 这里的关键字是显式定义的,您实际上是通过这样做来创建局部变量。

    那里还有一些其他问题,但@Stefan 已经涵盖了。

    【讨论】:

      【解决方案3】:

      TL;DR

      Ruby 不像 Python 等语言那样对空格敏感,但是在某些地方空格会让解析器感到困惑。此外,虽然您的某些代码可以工作,但它不是惯用的(它读起来像 JavaScript)并且性能较低。最后,就地操作符通常是 bang 方法,因此您需要区分更改接收者的方法和返回新结果的方法。

      惯用的替代方法

      出于文化原因,我更改了您的一些代码,但在数据方面保持接近您的意图。其余部分旨在展示如何以更惯用的方式做您想做的事情。

      这是一个使用字符串插值的更惯用和解析器友好的替代方案:

      def user_data(name, age, status)
        pp "name is #{name}; age is #{age}; status is #{status}"
      end
      

      在双引号内使用嵌入式表达式运算符#{expr} 进行字符串插值通常更有效,并且如果它支持#to_s 或#to_str 方法,则可以将值隐式转换为字符串。 Kernel#pKernel#pp 方法确保该方法返回一个值,并打印到 $stdout

      或者,您也可以使用其他构造,如 here-documents、String#sprintfString#format 和许多其他构造 printf 样式的插值,但上面的示例对于大多数 Ruby 爱好者来说最容易阅读,通常应该是如果您遵循大多数流行的 Ruby 样式指南,包括RuboCop's default style guide,那么您的首选。

      注意:插值适用于冻结字符串文字

      最后一点,即使您在文件顶部启用了冻结字符串文字“魔术注释”,这种类型的插值也将起作用,例如:

      #!/usr/bin/env ruby
      # frozen_string_literal: true
      

      RuboCop 和其他类似工具通常认为这是最佳实践。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-07
        相关资源
        最近更新 更多