Ruby构造函数self vs @

时间:2013-07-19 21:25:50

标签: ruby

我创建了以下简单类:

class Test
  def initialize(a, b)
    @a = a
    @b = b
  end

  def test
    puts @a
  end
end

有没有办法用@a替换self?我每次尝试这样做时都收到错误:

undefined method `a'

我这样做的原因是因为我想用两个参数创建一个新对象,然后对这些参数进行操作,如:

d = MyObject('title', 'Author')
d.showAuthor

6 个答案:

答案 0 :(得分:5)

class Test
  attr_accessor :a,:b   #creates methods a,b,a=,b= and @a and @b variables

  def initialize(a, b)
    self.a = a  #calls a=
    self.b = b  #calls b=
  end

  def test
    puts a  #calls method a; self.a would do the same.
  end

  def self.[](a,b)
    new(a,b)
  end
end

这会让你放弃新的(但你必须把parens改成方括号)所以你可以打电话:

d=Test['dog','cat']
d.a  #'dog'

答案 1 :(得分:2)

对于这些类,它可以完成并且实际上is done:Array,String,Integer,Float,Rational,Complex和Hash。如果您考虑同等重要的Test类(顺便说一句名字),请考虑:

class Test
  def initialize(a, b)
    @a = a
    @b = b
  end

  def test
    puts @a
  end
end

module Kernel
  def Test(*args)
    Test.new(*args)  #that's right, just call new anyway!
  end
end

book = Test('title', 'Author')
book.test # => title

由于Kernel模块由Object继承,因此全局命名空间现在具有Test方法。除非你绝对需要,否则不要这样做。

答案 2 :(得分:1)

您需要定义加速器,您可以使用attr_*

来完成
class Foo
  attr_accessor :a,:b

  def initialize(a, b)
    self.a = a
    self.b = b
  end
end

也不要在Ruby中使用camelCase,有一个名称为

的约定
  • 变量 - snake_case
  • 方法 - snake_case
  • 课程 - CapitalCamelCase
  • 常数 - CAPITAL_SNAKE_CASE

答案 3 :(得分:1)

当您使用self.a时,Ruby正在为a所代表的类寻找方法self,因此您得到一个未定义的方法错误(因为您没有定义一个名为a)。您可能正在寻找:

class Test
  attr_accessor :a, :b

  def initialize(a, b)
    self.a = a
    self.b = b
  end

  def test
    puts self.a   # "puts a" would be adequate here since it's not ambiguous
  end
end

答案 4 :(得分:1)

所以你需要从实例外部访问你的实例变量?你可以使用attr_accessor来做到这一点:

class Test
  attr_accessor :a
  attr_accessor :b

  def initialize(a, b)
    @a = a
    @b = b
  end
end

t = Test.new(:foo, :bar)
t.a
t.b

attr_accessor让你们都读写实例变量。如果您只需要阅读它,则可以使用attr_reader,如果您只需要更改它,则可以使用attr_writer

有关属性访问者的更多信息:https://stackoverflow.com/a/4371458/289219

答案 5 :(得分:1)

class MyClass

  def initialize(title,author)
    @title = title
    @author = author
  end

  def showAuthor
    @author
  end

end

那会产生......

d = MyClass.new("Grapes of Wrath", "Steinbeck")
d.showAuthor
=> "Steinbeck"
相关问题