Paul
Paul

Reputation: 26640

Get class variable from class directly

Following module:

class EnvParams
  def self.mailer
    environment.mailer
  end

  def self.router
    environment.router
  end

  def self.sms_gateway
    environment.sms_gateway
  end

  private

  def self.environment
    @@env ||= Hashie::Mash.new({data: {
        mailer: {
            address: ENV['DISP_MAILER_SERVER'],
            domain: ENV['DISP_MAILER_DOMAIN'],
            port: ENV['DISP_MAILER_PORT'],
            user_name: ENV['DISP_MAILER_USERNAME'],
            password: ENV['DISP_MAILER_PASSWORD'],
            sender: ENV['DISP_MAILER_SENDER']
        },
        router: {
            url: ENV['GTC_ROUTER_URL']
        },
        sms_gateway: {
            url: ENV['SMS_GATEWAY_URL']
        }
    }}).data
  end
end

had been created to concentrate all references to environment variables in one file and is intended to be queried for environment variables in such manner:

EnvParams.mailer.password

What I do not like is a bunch of def self.mailer, def self.router, def self.sms_gateway getters - one for each section. If a new section appears, a new getter has to be defined. How to avoid this without having to call an intermediate getter like EnvParams.environment.mailer.password ?

Upvotes: 1

Views: 75

Answers (2)

David Weiser
David Weiser

Reputation: 5195

Forwardable is a better solution, but to provide another option, you could dynamically create the methods:

class A
  def self.method_missing(name, *args, &blk)
    define_singleton_method name.to_sym do 
      environment.send(name.to_sym)
    end 
    self.send(name.to_sym)
  end
end

I found my inspiration from here. This is works on Ruby 1.9.

Upvotes: 2

javiyu
javiyu

Reputation: 1474

You can use delegators from Forwardable module ( http://www.ruby-doc.org/stdlib-2.0/libdoc/forwardable/rdoc/Forwardable.html )

class EnvParams
  extend Forwardable

  def_delegator :environment, :mailer
end

Upvotes: 1

Related Questions