Wrong number of arguments on initialize - ruby

In my Triangle class below, I have an initialize method that takes three arguments.
class Triangle
attr_accessor :side1, :side2, :side3
def initalize(one, two, three)
#side1 = one
#side2 = two
#side3 = three
end
end
When I create a new class and initialize it with three arguments,
one = Triangle.new(1,2,3)
puts one.side1
puts one.side2
puts one.side3
I get this error:
"lib/triangle.rb:21:in `initialize': wrong number of arguments (given 3, expected 0) (ArgumentError)".
What's up?

You have a typo:
def initalize # typo
def initialize # correct
BTW, a less manual way of handling the scenario in kind is:
def kind
:scalene if [#side1, #side2, #side3].uniq.length == 3
end

Related

Ruby wrong number of arguments in class instantitation

I am trying to make a battleship game in Ruby, but when I try to create an instance of the game board, I get "wrong number of arguments, 0 for 1". I dont see where I am going wrong as the initialize definition clearly accepts arguments.
class Board
attr_reader :grid, :default_grid
def intitalize(grid = self.class.default_grid, random = false)
#grid = grid
make_random_board if random
end
def self.default_grid
grid = Array.new(10){Array.new(10)}
end
def count
grid.flatten.count{|x| x == :s}
end
def self.random
self.new(self.default_grid, true)
end
def empty?(position = nil)
return true if position.nil?
else
false
end
def full?
grid.flatten.none?(&:nil?)
end
def place_random_ship
if full?
raise "error, board is full"
end
space = [rand(grid.length),rand(grid.length)]
until empty?(space)
space = [rand(grid.length),rand(grid.length)]
end
self[space] = :s
end
def make_random_board(count = 10)
count.times do
place_random_ship
end
end
end
emptygrid = Array.new(2){Array.new(2)}
myGame = Board.new(emptygrid)
You have a typo in your code. You should be using initialize instead of intitalize
And i believe the error you might have been getting would be ArgumentError: wrong number of arguments (1 for 0)
Which is because of your typo, the default class initialize method was used, which doesn't take in any arguments.
And something unrelated that i noticed in your code. You have defined a method named count and use variables named count. This is a code smell and i would suggest naming the method differently, because down the line, this might cause some bugs, that you might find hard to debug.

Making a Yhatzee game, array won't show up on screen

Ok so I just started learning ruby and I'm making a Yhatzee game, now this is where I'm currently at:
class Yhatzee
def dices
#dices.to_a= [
dice1=rand(1..6),
dice2=rand(1..6),
dice3=rand(1..6),
dice4=rand(1..6),
dice5=rand(1..6)
]
end
def roll_dice
#dices.to_a.each do |dice|
puts dice
end
end
end
x = Yhatzee.new
puts x.roll_dice
Now the reason i typed .to_a after the array is i kept getting a "uninitialized variable #dices" error, and that seemed to fix it, i have no idea why.
anyways on to my question, i currently don't get any errors but my program still won't print anything to the screen. I expected it to print out the value of each dice in the array... any idea what I'm doing wrong? It seems to work when i do it in a procedural style without using classes or methods so i assumed it might work if i made the 'dices' method public. But no luck.
There are a few issues here. Firstly #dices is nil because it is not set anywhere. Thus when you call #dices.to_a you will get []. Also the dices method will not work either because nil does not have a to_a= method and the local variables you are assigning in the array will be ignored.
It seems a little reading is in order but I would do something like the following: (Not the whole game just refactor of your code)
class Yhatzee
def dice
#dice = Array.new(5){rand(1..6)}
end
def roll_dice
puts dice
end
end
x = Yhatzee.new
puts x.roll_dice
There are alot of additional considerations that need to be made here but this should at least get you started. Small Example of how I would recommend expanding your logic: (I did not handle many scenarios here so don't copy paste. Just wanted to give you a more in depth look)
require 'forwardable'
module Yahtzee
module Display
def show_with_index(arr)
print arr.each_index.to_a
print "\n"
print arr
end
end
class Roll
include Display
extend Forwardable
def_delegator :#dice, :values_at
attr_reader :dice
def initialize(dice=5)
#dice = Array.new(dice){rand(1..6)}
end
def show
show_with_index(#dice)
end
end
class Turn
class << self
def start
t = Turn.new
t.show
t
end
end
attr_reader :rolls
include Display
def initialize
#roll = Roll.new
#rolls = 1
#kept = []
end
def show
#roll.show
end
def roll_again
if available_rolls_and_dice
#rolls += 1
#roll = Roll.new(5-#kept.count)
puts "Hand => #{#kept.inspect}"
show
else
puts "No Rolls left" if #rolls == 3
puts "Remove a Die to keep rolling" if #kept.count == 5
show_hand
end
end
def keep(*indices)
#kept += #roll.values_at(*indices)
end
def show_hand
show_with_index(#kept)
end
def remove(*indices)
indices.each do |idx|
#kept.delete_at(idx)
end
show_hand
end
private
def available_rolls_and_dice
#rolls < 3 && #kept.count < 5
end
end
end
The main problem with this code is that you are trying to use the #dices instance variable inside of the roll_dice method, however you are not defining the instance variable anywhere (anywhere that is being used). You have created the dices method but you are not actually instantiating it anywhere. I have outlined a fix below:
class Yhatzee
def initialize
create_dices
end
def roll_dice
#dices.each do |dice|
puts dice
end
end
private
def create_dices
#dices = Array.new(5){rand(1..6)}
end
end
x = Yhatzee.new
x.roll_dice
I have done some simple refactoring:
Created an initialize method, which creates the #dice instance variable on the class initialization.
Made the 'dices' method more descriptive and changed the method visibility to private so only the class itself is able to create the #dice.
Cleaned up the creation of the dices inside of the #dice instance variable
I have omitted the .to_a from the roll_dice method, now that we create the variable from within the class and we know that it is an array and it will be unless we explicitly redefine it.
UPDATE
Although I cleaned up the implementation of the class, it was kindly pointed out by #engineersmnky that I oversaw that the roll would return the same results each time I called the roll_dice function, I have therefore written two functions which will achieve this, one that defines an instance variable for later use and one that literally just returns the results.
class Yhatzee
def roll_dice
#dice = Array.new(5){rand(1..6)} # You will have access to this in other methods defined on the class
#dice.each {|dice| puts dice }
end
def roll_dice_two
Array.new(5){rand(1..6)}.each {|dice| puts dice } # This will return the results but will not be stored for later use
end
end
x = Yhatzee.new
x.roll_dice
x.roll_dice # Will now return a new result

Ruby: Wrong number of Arguments for a subclass changes number of arguments

I am very new to Ruby and I have been looking for an answer to my question, but haven't found an answer yet.
This is my code:
class Animal
def initialize(aName, anAge)
#name = aName
#age = anAge
end
end
class Cat < Animal
def initialize(aName, anAge, aBreed)
#breed = aBreed
super(aName, anAge, aBreed)
end
end
When I try to create a new cat object with defining three parameters, it says: ArgumentError: Wrong number of Arguments (3 for 2).
But when I do the same thing with two parameters I get (2 for 3).
I can't seem to figure it out...
Thanks for your help!
Your super class Animal constructor takes only two parameters aName and anAge. so you should only pass first two arguments of Cat to Animal.
class Cat < Animal
def initialize(aName, anAge, aBreed)
#breed = aBreed
super(aName, anAge)
end
end

attr_accessor or custom methods duplicate method names confusion

I do understand that Ruby supports short-hand style of calling methods i.e: 1.+(2) is same as 1+2 (and I still think if it related to my situation), but I got really confused why attr_accessor methods are neither duplicate (well, they should not be, as writer differs with = in its name) nor they differ with anything (except writer needs an argument) while accessing them outside active object.
My question is included in this code (in the second comment)
class Test
def initialize(number)
#number = number
end
def number
#number
end
def number=(n)
#number = n
end
end
t = Test.new(12)
puts t.number # => 12
t.number = 13 # Why does it do what t.number=(13) should do
puts t.number # => 13
I wonder why t.number = 13 works, when it points to a method which should only return a number and moreover how does it set a new value when t.number=(13) is not called instead.
t.number = 13 is just a shorthand for t.number=(13), they are effectively the same statement in Ruby.
attr_accessor :b creates the equivalent of the following two methods:
def b
#b
end
def b=(new_val)
#b = new_val
end
So in your code example, you could replace the two methods #number and #number= with attr_accessor :number

Ruby, assert_equal of two arrays of objects

I have the following situation. I am trying to write a unit test for an array of objects. The object is defined something like this:
class Element
attr_reader :title, :season, :episode
def initialize ( name, number )
#name = name
#number = number
end
def to_s
number = "%02d" % #number
result = "Number " << number << " " << #name
result
end
end
During the test I assert two arrays which both contain three elements, the elements are identical and even the order is identical still I get an error that the assert isn't equal. I guess I am missing something really basic here, whats the catch?
If I compare each element by the to_s method, the assert is correct.. Is that the way it should be done in the first place?
Try declaring a method == for your class, with the following code.
def ==(other)
self.to_s == other.to_s
end
Sidenote, you might want to refactor your to_s method too, for some concise code.
def to_s
"Number %02d #{#name}" % #number
end
Edit:
Numbers already have an == method defined (https://github.com/evanphx/rubinius/blob/master/kernel/bootstrap/fixnum.rb#L117).
Ruby compares arrays by running an == compare on each element of an Array. Here's the implementation of == on Arrays, as done in Rubinius (a Ruby implementation written almost completely in Ruby itself) https://github.com/evanphx/rubinius/blob/master/kernel/common/array.rb#L474.
If you leave out various error detections, it basically runs an == on all the elements of the array, recursively, and returns true if all of them match.

Resources