Search code examples
crystal-lang

How to call a method from a class inside the same module


How do I call redis from a struct or a class?

module A::Cool::Module
  redis = Redis.new(host: ENV["REDIS_DEV_HOST"], port: 18163)
  redis.auth(ENV["REDIS_DEV_AUTH"])

  struct CoolStruct
    def CoolFunciton
       redis # => undefined method 'redis' for A::Cool::Module:Module
    end
  end
end

I've tried the following without success

module A::Cool::Module
  @@redis = Redis.new(host: ENV["REDIS_DEV_HOST"], port: 18163)
  @@redis.auth(ENV["REDIS_DEV_AUTH"])

  struct CoolStruct
    def CoolFunciton
       @@redis # => can't infer the type of class variable '@@redis'
    end
  end
end
module A::Cool::Module
  module DB
     redis = Redis.new(host: ENV["REDIS_DEV_HOST"], port: 18163)
     redis.auth(ENV["REDIS_DEV_AUTH"])
  end


  struct CoolStruct
    include A::Cool::Module::DB
    def CoolFunciton
       redis # => undefined local variable or method 'redis'
    end
  end
end
module A::Cool::Module
  module DB
     redis = Redis.new(host: ENV["REDIS_DEV_HOST"], port: 18163)
     redis.auth(ENV["REDIS_DEV_AUTH"])
  end


  struct CoolStruct
    include A::Cool::Module::DB
    def CoolFunciton
       A::Cool::Module::DB.redis # => undefined method 'redis'
    end
  end
end

I really have no idea how to do it. And I don't want to create a redis connection for each class where I need redis.


Solution

  • Case is significant in Crystal. A module can have constants, which will be accessible throughout the module's scope (note the uppercase):

    module A::Cool::Module
      REDIS = ...
      ...
    end
    

    (Also, you should really use snake_case, not TitleCase for a method name; so cool_function, not CoolFunction.)