避免在ruby中初始化方法

时间:2016-01-28 15:24:21

标签: ruby

我正在编写下面的Ruby程序

class Animal
  attr_reader :name, :age

  def name=(value)
    if value == ""
      raise "Name can't be blank!"
    end
    @name = value
  end

  def age=(value)
    if value < 0
      raise "An age of #{value} isn't valid!"
    end
    @age = value
  end

  def talk
    puts "#{@name} says Bark!"
  end

  def move(destination)
    puts "#{@name} runs to the #{destination}."
  end

  def report_age
    puts "#{@name} is #{@age} years old."
  end
end

class Dog < Animal
end

class Bird < Animal
end

class Cat < Animal
end

whiskers = Cat.new("Whiskers")
fido = Dog.new("Fido")
polly = Bird.new("Polly")
polly.age = 2
polly.report_age
fido.move("yard")
whiskers.talk

但是当我运行它时,会出现这个错误:

C:/Users/akathaku/mars2/LearningRuby/Animal.rb:32:in `initialize': wrong number of arguments (1 for 0) (ArgumentError)
    from C:/Users/akathaku/mars2/LearningRuby/Animal.rb:32:in `new'
    from C:/Users/akathaku/mars2/LearningRuby/Animal.rb:32:in `<main>'

我的调查显示我应该创建像这样的对象

whiskers = Cat.new("Whiskers")

然后我的代码中应该有一个initialize方法,它将使用值“Whiskers”初始化实例变量。

但是如果我这样做那么我使用的属性访问器的目的是什么?或者就像我们只能使用一个,如果我必须使用属性访问器,那么我应该避免在对象创建期间初始化实例变量。

3 个答案:

答案 0 :(得分:3)

initialize是您的类的构造函数,它在创建对象时运行。

属性访问器用于读取或修改现有对象的属性。

对构造函数进行参数化可以为您提供一种简洁明了的方法来为对象的属性赋值。

whiskers = Cat.new("Whiskers")

看起来更好,写起来比

更容易
whiskers = Cat.new
whiskers.name = "Whiskers"

在这种情况下,initialize的代码应该类似于

class Animal
  ...
  def initialize(a_name)
    name = a_name
  end
  ...
end

答案 1 :(得分:0)

所有attr_reader :foo都会定义方法def foo; @foo; end。同样,attr_writer :foodef foo=(val); @foo = val; end也这样做。他们不会假设您想要如何构建initialize方法,并且您必须添加类似

的内容
def initialize(foo)
  @foo = foo
end

但是,如果您想减少属性的样板代码,可以使用StructVirtus之类的内容。

答案 2 :(得分:0)

您应该在类名下面定义一个方法,例如

def initialize name, age
@name = name
@age = age
end