1

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!

3
  • 1
    What do you mean by the same parameters? In the example you pass different ones to each method - to method 1,2,3, to method2 4,5,6 etc Commented Oct 11, 2019 at 18:37
  • mrzasa, I meant to pass the same parameters to each method inside the same class. Commented Oct 11, 2019 at 19:48
  • You can format your code however you like but the Ruby convention is to indent two spaces. Commented Oct 11, 2019 at 21:35

3 Answers 3

2

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
Sign up to request clarification or add additional context in comments.

Comments

2

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)

Comments

1

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

1 Comment

pjs, thank you as well for the good example but my intention was to simplify the code and avoid the repetition of passing the same parameters to each method over and over, as shown in my example and also in your example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.