/errors/ruby/wrong-number-of-arguments
Ruby ArgumentError: wrong number of arguments (given 1, expected 0)
- tool
- Ruby
- exit code
- 1
- versions
- Ruby 3.x
- os
- any
ArgumentError: wrong number of arguments (given 1, expected 0) means a method was called with a different number of arguments than its definition accepts: here one argument for a method that takes none. Ruby checks the count on every call. The first line of the backtrace (in 'greet') is the method being called, the next line is the caller. Change the call to match the method, or the method to accept the arguments. Other forms of the message are (given 0, expected 1), (given 3, expected 1..2) for optional arguments and (given 1, expected 0; required keyword: name) for keywords.
Reproduce it
CRuby 3.4 compiled to WebAssembly (ruby.wasm, the official Ruby project build), run with Node.js:
npm init -y >/dev/null
npm install --silent --no-audit --no-fund @ruby/3.4-wasm-wasi@2.8.1 @ruby/wasm-wasi@2.8.1 >/dev/null 2>&1
cat > app.rb <<'EOF'
def greet
"hi"
end
def connect(host, port = 5432)
"#{host}:#{port}"
end
def create_user(name:, admin: false)
"#{name} admin=#{admin}"
end
class Point
def initialize(x, y)
@x = x
@y = y
end
end
calls = {
'greet("Ada")' => -> { greet("Ada") },
'connect' => -> { connect },
'connect("db", 5432, "x")' => -> { connect("db", 5432, "x") },
'create_user({ name: "Ada" })' => -> { create_user({ name: "Ada" }) },
'Point.new(1)' => -> { Point.new(1) },
}
calls.each do |code, fn|
fn.call
rescue ArgumentError => e
puts "#{code.ljust(30)} #{e.class}: #{e.message}"
end
puts "RUBY_VERSION #{RUBY_VERSION}"
EOF
cat > run.mjs <<'EOF'
import fs from "node:fs/promises";
import { DefaultRubyVM } from "@ruby/wasm-wasi/dist/node";
const wasm = await WebAssembly.compile(await fs.readFile("node_modules/@ruby/3.4-wasm-wasi/dist/ruby+stdlib.wasm"));
const { vm } = await DefaultRubyVM(wasm);
vm.eval(await fs.readFile("app.rb", "utf8") + "\n$stdout.flush");
EOF
node --no-warnings run.mjsOutput
greet("Ada") ArgumentError: wrong number of arguments (given 1, expected 0)
connect ArgumentError: wrong number of arguments (given 0, expected 1..2)
connect("db", 5432, "x") ArgumentError: wrong number of arguments (given 3, expected 1..2)
create_user({ name: "Ada" }) ArgumentError: wrong number of arguments (given 1, expected 0; required keyword: name)
Point.new(1) ArgumentError: wrong number of arguments (given 1, expected 2)
RUBY_VERSION 3.4.1Fix it
Make the call match the definition, or make the definition accept what callers pass:
def greet(name = "world") # optional argument with a default
"hi #{name}"
end
def log(message, *tags) # any number of extra arguments
puts "[#{tags.join(',')}] #{message}"
end
create_user(name: "Ada") # pass keywords, not a positional hash
opts = { name: "Ada", admin: true }
create_user(**opts) # splat a hash into keyword argumentsRuby 3 keyword arguments
Since Ruby 3.0, a hash passed as the last positional argument is no longer converted into keyword arguments. Code written for Ruby 2.7 that calls create_user({ name: "Ada" }) or create_user(opts) now fails with wrong number of arguments (given 1, expected 0; required keyword: name). Add ** (create_user(**opts)) or write the keywords out.