0

I have created folowing simple class:

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

  def test
    puts @a
  end
end

IS there a way to replace @a with self? Everytime I tried to do this I received an error:

undefined method `a'

The reason I am doing this is because I would like to create a new object with two parameters, and later operate on these parameters like:

d = MyObject('title', 'Author')
d.showAuthor
David Weiser
  • 5,190
  • 4
  • 28
  • 35
meso_2600
  • 1,940
  • 5
  • 25
  • 50

6 Answers6

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

This will let you drop the new (but you have to change the parens to square brackets) So you can call:

d=Test['dog','cat']
d.a  #'dog'
Shawn Balestracci
  • 7,380
  • 1
  • 34
  • 52
2

It can be done and actually is done for these classes: Array, String, Integer, Float, Rational, Complex and Hash. If you consider the Test class (bad name by the way) of equal importance then consider:

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

Since the Kernel module is inherited by Object, the global namespace now has a Test method. Don't do this unless you absolutely need it.

steenslag
  • 79,051
  • 16
  • 138
  • 171
  • 1
    BTW: it's common practice to make such methods that are not actually intended to be *called* as methods (they are more like global procedures) `private` so that you don't accidentally call them like `foo.Test('bla')`. – Jörg W Mittag Jul 20 '13 at 04:13
1

You need to define accesors, you can do it using attr_*:

class Foo
  attr_accessor :a,:b

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

Also do not use camelCase in Ruby, there is convention to name:

  • variables - snake_case
  • methods - snake_case
  • classes - CapitalCamelCase
  • constants - CAPITAL_SNAKE_CASE
Hauleth
  • 22,873
  • 4
  • 61
  • 112
  • 2
    `attr_accessible` is removed from ActiveRecord and was never part of Ruby. You probably meant to say `attr_accessor`. – steenslag Jul 19 '13 at 21:39
1

When you use self.a, Ruby is looking for a method a for the class represented by self, so you get an undefined method error (since you did not define a method called a). You probably are looking for:

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
lurker
  • 56,987
  • 9
  • 69
  • 103
1

So you need to access your instance variables from outside the instance? You can use attr_accessor to do that:

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 let's you both read and write the instance variable. If you only need to read it, you can use attr_reader, and if you only need to change it you can use attr_writer.

More on attribute accessors: https://stackoverflow.com/a/4371458/289219

Community
  • 1
  • 1
Robert Kajic
  • 8,689
  • 4
  • 44
  • 43
1
class MyClass

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

  def showAuthor
    @author
  end

end

That will produce...

d = MyClass.new("Grapes of Wrath", "Steinbeck")
d.showAuthor
=> "Steinbeck"
SteveTurczyn
  • 36,057
  • 6
  • 41
  • 53