Skip to content

Instantly share code, notes, and snippets.

@eqdw
Created July 20, 2015 17:18
Show Gist options
  • Save eqdw/41e976520a2792846032 to your computer and use it in GitHub Desktop.
Save eqdw/41e976520a2792846032 to your computer and use it in GitHub Desktop.
# I want to make a utility class that encapsulates a bunch of useful
# methods. It doesn't really need any state, it's really more of a
# namespace to put the methods in. Say, for example, a math utility
# Math.random => random number
# Math.sin(x) => sine(x)
# Math.PI => 3.14159265......
# etc.
# Wat do?
#naieve solution (assume the method bodies are implemented)
class Math
def self.random; end
def self.sin; end
def self.PI; end
end
# This works, defining everything as class-level methods ("static" in C++/Java)
# But it makes it difficult to test for a wide variety of reasons (in Ruby, anyway)
# This is better
class Math
def random; end
def sin; end
def PI; end #note: I'm cheating on syntax. ALLCAPS is a constant var, not method identifier
# Equivalent to auto generating
# def self.random; Math.new.random; end
# def self.sin; Math.new.sin; end
# def self.PI; Math.new.PI; end
# for every instance method
def self.method_missing(name, args, &block)
instance = Math.new
if instance.responds_to?(name)
instance.name
else
super(name, args, &block)
end
end
end
# This is a shitty example, but in the general case, writing things like this allows you
# to decouple setting up the state from running a given function, and gives you more
# points to hook into for testing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment