Skip to content

Instantly share code, notes, and snippets.

@jwoertink
Created April 4, 2014 03:55
Show Gist options
  • Select an option

  • Save jwoertink/9967795 to your computer and use it in GitHub Desktop.

Select an option

Save jwoertink/9967795 to your computer and use it in GitHub Desktop.
# Looking to write an API like this.
# Before calling Something::Thing#search, there has to be an instance of Something::Connection
# There are other classes to be used that require the connection instance as well.
conn = Something::Connection.new
things = Something::Thing.search('stuff') # requires that an instance of Something::Connection exists
other = Something::Other.stuff('more') # also requires that instance exists
conn.close
# How can I save that instance in such a way that any other classes in that module will see that,
# without passing that variable every single time?
@seashootz
Copy link

I'm kind of curious why Thing#search and Other#stuff are class methods. If Thing only performs a search, I think it's fine to create a throwaway object after its done.

If they are class methods my best guess (probably awful) is to encapsulate that all in a class.

class ConnectionService
  def initialize
    @connection = Something::Connection.new
  end

  def search(string)
     Something::Thing.search(string)
  end

  def other(string)
      Something::Other.search(string)
  end

  def close
     @connection.close
  end
end

so it looks like

ConnectionService.new.search('blah')
ConnectionService.new.other('blah')
ConnectionService.close # or just use a new class if you need to

If they're instance methods, what Paul showed me was:

class Something::Thing
  def initialize(connection)
    @connection = connection
  end

  def search
    # whatever elasticsearch?
  end
end

class Something::Other
  def initialize(connection)
    @connection = connection
  end

  def stuff
    # stuff
  end
end

class ConnectionFactory
  def initialize
    @connection = Something::Connection.new
  end

  def create_thing
     Something::Thing.new(@connection)
  end

  def create_other
     Something::Other.new(@connection)
  end
end

So the calls wold look like:

ConnectionFactory.create_thing.search('stuff')
ConnectionFactory.create_other.search('more')

I ran into something similar and would love to know a better way to do this!

@seashootz
Copy link

whoa, thanks @alexpeachey

class Something::Connection
  include Singleton
end
require 'active_support'

class Something::Thing
  cattr_accessor :connection do
    Something::Connection.instance
  end

  def search
    # much better
  end
end

class Something::Other
  cattr_accessor :connection do
    Something::Connection.instance
  end

  def stuff
    # like a lot better
  end
end

I hope this is right

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment