Instance variables and method parameters

(Sam Kong) #1

Hello!

I have a question about using instance member variables in a method.
This is rather a general OO implementation question than specific Ruby
one.

As you know, all instance methods can access insatance member variables
freely.
Thus, instance member variables are like global variables in a class (I
mean... in an object).
So you don't have to pass those data beween methods in a class.

However, I feel more comfortable when I make those data passed as
arguments.

See the examples (very simple and stupid one):

class Tax1
  def initialize(emp_id)
    @emp_id = emp_id
  end

  def tax
#explicitly pass the argument even if get_salary can access @emp_id
    salary = get_salary(@emp_id)
    return salary * 0.1
  end

  def get_salary(emp_id)
    #do some calcuation using emp_id and data from db
    #...
    return salary
  end

  private :get_salary

end

class Tax2
  def initialize(emp_id)
    @emp_id = emp_id
  end

  def tax
    salary = get_salary #no argument
    return salary * 0.1
  end

  def get_salary
    #do some calcuation using @emp_id and data from db
    #...
    return salary
  end

  private :get_salary

end

For public methods, it's obvious that you shouldn't put arguments as
the format affects objects' clients.
But for private methods, I like to make the methods more standalone
(not depending the member variables).

Is this an acceptable habit?
Do you feel the same way as I do?

Thanks.

Sam

(Robert) #2

Hello!

I have a question about using instance member variables in a method.
This is rather a general OO implementation question than specific Ruby
one.

As you know, all instance methods can access insatance member
variables freely.
Thus, instance member variables are like global variables in a class
(I mean... in an object).
So you don't have to pass those data beween methods in a class.

However, I feel more comfortable when I make those data passed as
arguments.

See the examples (very simple and stupid one):

class Tax1
def initialize(emp_id)
@emp_id = emp_id
end

def tax
#explicitly pass the argument even if get_salary can access @emp_id
salary = get_salary(@emp_id)
return salary * 0.1
end

def get_salary(emp_id)
#do some calcuation using emp_id and data from db
#...
return salary
end

private :get_salary

end

class Tax2
def initialize(emp_id)
@emp_id = emp_id
end

def tax
salary = get_salary #no argument
return salary * 0.1
end

def get_salary
#do some calcuation using @emp_id and data from db
#...
return salary
end

private :get_salary

end

For public methods, it's obvious that you shouldn't put arguments as
the format affects objects' clients.
But for private methods, I like to make the methods more standalone
(not depending the member variables).

Is this an acceptable habit?

Well, acceptable by whom? If you work on this code with other people you should ask them. If you're doing it all on your own and don't plan to distribute it you decide. :slight_smile:

Do you feel the same way as I do?

Not exactly. I usually draw a line between general algorithms and methods specific to an instance. When implementing general algorithms, I choose static methods in Java and class methods in Ruby thus making clear they don't depend on instance state.

class SillyExample
  attr :foo

  def initialize(foo) @foo = foo end

  def to_s
    # instance method
    SillyExample.transform foo
    # alternative invocation:
    # self.class.transform foo
  end

  def self.transform(s)
    # algorithm
    s.gsub(/^.*$/, '<\\&>')
  end
end

In your example I'd probably try to keep the DB code completely out of the class. There are plenty smart ways in Ruby to fetch data from a DB (ActiveRecord etc.) which don't make it necessary to scatter all persistency code throughout classes. If you want it in there then I'd prefer a mixin module that does all the db stuff. This can be reused by several classes.

HTH

Kind regards

    robert

···

Sam Kong <sam.s.kong@gmail.com> wrote:

(Sam Kong) #3

Hi, Robert!

Not exactly. I usually draw a line between general algorithms and methods
specific to an instance. When implementing general algorithms, I choose
static methods in Java and class methods in Ruby thus making clear they
don't depend on instance state.

This is exactly what I was asking for.
I'll follow the way you do.
Thanks.

Sam