Skip to content

Instantly share code, notes, and snippets.

@mattwynne
Forked from bmabey/object_locators.rb
Created March 15, 2009 18:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattwynne/79496 to your computer and use it in GitHub Desktop.
Save mattwynne/79496 to your computer and use it in GitHub Desktop.
module ObjectLocators
def the_policy
if @policy
@policy
else
case Policy.count
when 0
raise "There is no @policy variable defined and no policy in the DB! Establish state in previous step or create a new policy."
when 1
Policy.first
else
raise "There are multiple policies in DB and no @policy variable set! Please disambiguate the state in previous step."
end
end
end
end
World { |world| world.extend(ObjectLocators) }
# TODO Break me into 3 parts and use them in identified_model(str).
IDRE = /(?:the (?:[^ ]+)|the (?:[^ ]+) "(?:.+)"|"(?:.+)")/ unless defined?(IDRE)
module StuffManagment
class StuffContainer < Hash
def find_thing(opts)
expected_type = opts[:type]
name = opts[:name]
thing = self[name]
raise("Unable to find any object in stuff[] with the name '#{name}' that you asked for, boss. I could however offer you one of the following: #{self.to_s}") unless thing
raise("That thing you asked for, it appears to be a #{thing.class.name} when you asked for a #{expected_type.name}") unless thing.is_a?(expected_type)
thing
end
def to_s
result = ["#{self.length} items in total:"]
self.each do |key, thing|
result << "the #{thing.class.name} \"#{key}\""
end
result.join("\n")
end
def []=(key, value)
# Opportunity for logging / debugging here
super
# puts self.to_s
end
end
def clear_stuff
@stuff = StuffContainer.new
end
def stuff
return @stuff if @stuff
# puts "had to create a new stuff"
clear_stuff
end
SEARCH_MODULES = ['']
# expects one of:
# the Artist
# the Artist "Jude"
# "Jude" <- not sure about this one
def identified_model(str)
case str
when /^the ([^ ]+) "(.+)"$/
klass = safe_constantize($1)
instance = stuff.find_thing(:type => klass, :name => $2)
instance.reload
return instance
when /^the ([^ ]+)$/
return implicit_model($1)
when /^"(.+)"$/
instance = stuff[$1]
instance.reload if instance
return instance
end
raise "No such instance: '#{str}'.\n Current stuff: #{stuff.to_s}"
end
# expects:
# Artist
def implicit_model(str)
klass = safe_constantize(str)
klass.count.should == 1
klass.first
end
def safe_constantize(str)
begin
recorded_exception = nil
# Search all the specified namespaces in order and return the first constant found.
SEARCH_MODULES.each do |mod|
begin
return "#{mod}::#{str}".constantize
rescue NameError => e
recorded_exception = e
end
end
error_message = "\"#{str}\" does not appear to be a valid object in the domain. Did you mean \"#{str.classify}\"?"\
+ "\nDetailled error message:\n#{recorded_exception.message}"
raise NameError.new(error_message)
end
end
end
World{ |world| world.extend(StuffManagement) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment