Search code examples
rubydesign-patternsinterfacesequel

How can I achieve this result in ruby?


I was reading the Sequel's docs and I'm got curious about the technique used in the following code snippet:

class Post < Sequel::Model(:my_posts)
  (...)
end

The Sequel::Model(:my_posts) sets the database table for the model. I'm curious specifically about the parenthesis in Model(:my_posts). I like this interface, but how can I achieve that? It's a bit weird... Seems like the Model can be called as a method... Which is this technique? Can somebody give me an example?


Solution

  • Normally when you use :: with module or class, ruby will try to find expression after :: in constants.

    Example::First => as constant
    Example::First() => as method
    

    Run this code:

    module Example
      class << self
        def First(a)
          puts a
        end
      end
    
      module First
      end
    end
    

    Usage:

    Example::First(1) # => prints 1
    

    When you use class << self you open self's class so that methods can be redefined for the current self object (which inside a class or module body is the class or module itself). Read good question/answers on SO.

    It's good practice, while not mandatory, to start the method name with a lower-case character, because names that start with capital letters are constants in Ruby. It's still possible to use a constant name for a method, but you won't be able to invoke it without parentheses, because the interpeter will look-up for the name as a constant

    From What are the restrictions for method names in Ruby?