简体   繁体   中英

`initialize': wrong number of arguments (given 3, expected 0) (ArgumentError)

I have the following bit of code:

load 'Point.rb'
class Triangle

    def initialize(x, y , z)
        if !x.is_a?(Point) || !y.is_a?(Point) || !z.is_a?(Point)
            puts "Invalid data, a Triangle can only be initialized through points"
        else
            @x=x
            @y=y
            @z=z
            @type=type(x, y, z)
        end
    end

    def type(x, y, z)
        if x.distance(y) == y.distance(z) && y.distance(z) == z.distance(x)
            return "equilateral"
        elsif x.distance(y)== y.distance(z) || y.distance(z) == z.distance(x) || z.distance(x) == x.distance(y)
            return "isosceles"
        else
            return "scalene"
        end
    end

    attr_accessor :type
end

I'm calling the method like this:

load 'Triangle.rb'

x=Point.new(0,0)
y=Point.new(1,1)
z=Point.new(2,0)
triangle=Triangle.new x, y, z
puts triangle.type

The class Point is as follows:

class Point

    def initialize (x=0, y=0)
        @x=x.to_i
        @y=y.to_i
    end

    def ==(point)
        if @x==point.x && @y==point.y
            return true
        else
            return false
        end
    end

    def distance(point)
        Math.hypot((@x-point.x),(@y-point.y))
    end

    attr_accessor :y
    attr_accessor :x
end

The error is as follows:

Triangle.rb:11:in `initialize': wrong number of arguments (given 3, expected 0) (ArgumentError)
    from Triangle_test.rb:6:in `new'
    from Triangle_test.rb:6:in `<main>'

Please tell if the whole code is just garbage.

In your Triangle class you have method type which accepts three parameters, and then below you have attr_accessor :type which overwrites that 3-parameters method with a parameterless getter.

That's why you get that error when you do this in the initializer

@type=type(x, y, z)

Here's a cleaned-up version of your code:

  • removed unneeded if's
  • removed unneeded return's
  • defined a private calculate_type method
  • replaced attr_accessor with attr_reader
  • renamed x,y,z with a,b,c to avoid confusion between coordinates and points

class Point
  attr_reader :x, :y
  def initialize(x = 0, y = 0)
    @x = x.to_i
    @y = y.to_i
  end

  def ==(point)
    @x == point.x && @y == point.y
  end

  def distance(point)
    Math.hypot((@x - point.x), (@y - point.y))
  end
end

class Triangle
  attr_reader :a, :b, :c, :type

  def initialize(a, b, c)
    raise 'Invalid data, a Triangle can only be initialized through points' unless [a, b, c].all? { |p| p.is_a?(Point) }
    @a, @b, @c = a, b, c
    @type = calculate_type
  end

  private

  def calculate_type
    if a.distance(b) == b.distance(c) && b.distance(c) == c.distance(a)
      'equilateral'
    elsif a.distance(b) == b.distance(c) || b.distance(c) == c.distance(a) || c.distance(a) == a.distance(b)
      'isosceles'
    else
      'scalene'
    end
  end
end

a = Point.new(0, 0)
b = Point.new(1, 1)
c = Point.new(2, 0)
triangle = Triangle.new a, b, c
puts triangle.type
# isosceles

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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