Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby: Adding things to initialize method through modules

In Ruby I want to have a class include a series of modules and have these individual modules execute a block or method (or just find some way to edit an instance variable) when initializing that class.

I know I can do this by creating a method in the module and then calling it in the class' initialize method, but I want some way to do this by simply including the module and calling one method to execute any code the modules add to initialize, that way I can have a large amount of things included in a class without worrying about adding a line of code in the initialize method for every single module included.

I've checked out aliasing, super, and related things but haven't gotten anything...

If it helps to understand what I'm hoping to accomplish here's some pseudocode:

module Mod1  
    call_this_block_on_initialize { @a.push 4 }  
end  
  
module Mod2  
    call_this_block_on_initialize { @a.push 5 }  
end  
  
class Test  
    attr_accessor :a  
    include Mod1  
    include Mod2  
  
    def initialize  
      @a = [1, 2, 3]  
      call_those_blocks_set_by_mods  
    end  
end  

t = Test.new
t.a # returns [1, 2, 3, 4, 5]

This may be a bit wordy but I think the title sums up what I'm trying to do. Thanks for any help!

like image 524
thIIIrd Avatar asked Nov 06 '12 19:11

thIIIrd


People also ask

What is the Initialize method in Ruby?

The initialize method is part of the object-creation process in Ruby and it allows us to set the initial values for an object. Below are some points about Initialize : We can define default argument. Defining initialize keyword is not necessary if our class doesn’t require any arguments.

What is a module in Ruby?

puts "Ruby Tutorial!" Welcome to GFG Portal! Ruby Tutorial! Topic - Module 50 Use of Modules: A module is a way categorize the methods and constants so that user can reuse them. Suppose he wants to write two methods and also want to use these methods in multiple programs.

What is ruby module and mixin?

Ruby - Modules and Mixins. Modules are a way of grouping together methods, classes, and constants. Modules give you two major benefits. Modules provide a namespace and prevent name clashes. Modules implement the mixin facility.

How to use a module inside of a class?

The user can use the module inside the class by using include keyword. In this case, the module works like a namespace. puts "Welcome to GFG Portal!" puts "Ruby Tutorial!"


1 Answers

There are a few ways you can do this. This example will redefine the initialize method and add whatever extra code you want:

module MyModule
  def self.included(base) # built-in Ruby hook for modules
    base.class_eval do    
      original_method = instance_method(:initialize)
      define_method(:initialize) do |*args, &block|
        original_method.bind(self).call(*args, &block)
        @a.push 4 # (your module code here)
      end
    end
  end
end

class Test  
  attr_accessor :a  

  def initialize  
    @a = [1, 2, 3]    
  end  

  # It must be included after the `initialize` 
  # definition or the module won't find the method:
  include MyModule
end  

However: I think what you really want is subclassing. If you have a lot of classes with similar behavior, as it seems you do, ask yourself if there is a natural abstract parent class. Can you explain what you did with super and why it didn't work?

like image 200
Zach Kemp Avatar answered Oct 09 '22 16:10

Zach Kemp