Steve
Steve

Reputation: 347

Ruby: Passing same parameters to multiple methods inside a class

Sorry if this is too basic to ask. Say, I have 5 methods inside a same class. When I call each method, I need to pass the same parameters. Is there a way to simplify this and avoid the repetition?

class Class1
        def method1(arg1, arg2, arg3)
                puts arg1, arg2, arg3
        end
        def method2(arg1, arg2, arg3)
                puts arg1, arg2, arg3
        end
        def method3(arg1, arg2, arg3)
                puts arg1, arg2, arg3
        end
        def method4(arg1, arg2, arg3)
                puts arg1, arg2, arg3
        end
        def method5(arg1, arg2, arg3)
                puts arg1, arg2, arg3
        end
end

obj1 = Class1.new

obj1.method1(1, 2, 3)
obj1.method2(4, 5, 6)
obj1.method3(7, 8, 9)
obj1.method4(10, 11, 12)
obj1.method5(13, 14, 15)

Thanks in advance!

Upvotes: 1

Views: 1193

Answers (3)

ArtuX
ArtuX

Reputation: 374

Using constructor might be helpful:

class MyClass

  def initialize(arg1, arg2, arg3)
    @arg1, @arg2, @arg3 = arg1, arg2, arg3
  end

  def method_one
    puts @arg1, @arg2, @arg3
  end

  def method_two
    puts @arg1, @arg2, @arg3
  end

end

my_obj = MyClass.new(1,7,13)
my_obj.method_one  #=> 1 7 13 
my_obj.method_two  #=> 1 7 13

You can also be more succinct using Struct:

MyClass = Struct.new(:arg1, :arg2, :arg3) do

  def method_one
    puts arg1, arg2, arg3
  end

  def method_two
    puts arg1, arg2, arg3
  end

end

my_obj = MyClass.new(1,7,13)
my_obj.method_one  #=> 1 7 13 
my_obj.method_two  #=> 1 7 13
puts my_obj.arg2   #=> 7

Upvotes: 2

Myst
Myst

Reputation: 19221

EDIT: I just notices pjs's answer (I skimmed the beginning and somehow missed the content)... go up-vote that one, it was here first and it's the same solution.

If you don't control the class (you can't use class instance variables), consider using the splat (*) operator.

i.e.:

class MyClass
    def mthd1(arg1,arg2,arg3)
      #...
    end
    def mthd2(arg1,arg2,arg3)
      #...
    end
    def mthd3(arg1,arg2,arg3)
      #...
    end
    def mthd4(arg1,arg2,arg3)
      #...
    end
end
foo = MyClass.new
args_to_pass = [1,2,3]
foo.mthd1(*args_to_pass)
foo.mthd2(*args_to_pass)
foo.mthd3(*args_to_pass)
foo.mthd4(*args_to_pass)

Or even monkey patch the class to add a method that does it for you (untested):

class MyClass
   # monkey patching
   MULTI_METHOD_NAMES = [:mthd1, :mthd2, :mthd3, :mthd4]
   def multi_func *args
       MULTI_METHOD_NAMES {|m| self.send(m, *args)
   end    
end
# use:
foo = MyClass.new
foo.multi_func(1, 2, 3)

Upvotes: 2

pjs
pjs

Reputation: 19855

Your example doesn't agree with your statement that you want the same arguments, but I'm charging ahead with an alternate implementation of your example.

class Klass
  # slightly more descriptive output from the methods...
  def method1(a1, a2, a3)
    puts "in method1"
    puts "#{a1}, #{a2}, #{a3}"
  end

  def method2(a1, a2, a3)
    puts "in method2"
    puts "#{a1}, #{a2}, #{a3}"
  end

  def method3(a1, a2, a3)
    puts "in method3"
    puts "#{a1}, #{a2}, #{a3}"
  end
end

# store the method symbols and arguments in arrays...   
m = [:method1, :method2, :method3]
args = [1, 2, 3]

obj = Klass.new
# ...which allows us to iterate over them.
m.each do |method|
  obj.send(method, *args)
  args.map! { |x| x + 3 }  # update the args as in the given example
end

produces:

in method1
1, 2, 3
in method2
4, 5, 6
in method3
7, 8, 9

Upvotes: 1

Related Questions