Skip to content

Instantly share code, notes, and snippets.

@tatey
Created November 28, 2012 06:17
Show Gist options
  • Select an option

  • Save tatey/4159364 to your computer and use it in GitHub Desktop.

Select an option

Save tatey/4159364 to your computer and use it in GitHub Desktop.
Short hand for an attribute writer with a default value
# When using dependency injection, I often find myself storing the dependency as
# an attribute on the object. This is fine, except when you squint at the class there
# looks to be more methods then what's really needed to understand the class.
#
# A typical class with dependency injection might look like this
class TimeParam
attr_writer :parser
def initialize value
@value = value
end
def date_time
parser.parser value if value
end
def parser
@parser ||= DateTime
end
end
# Wouldn't it be nice if it looked like this instead?
class TimeParam
include Dependency
dependency :parser, DateTime
def initialize value
@value = value
end
def date_time
parser.parser value if value
end
end
# And just like the first implementation, we can swap it out like this.
class TimeParamTest < MiniTest::Unit::TestCase
def test_date_time
parser = MiniTest::Mock.new
parser.expect :parse, [String], DateTime.new('2012-12-12')
time_param = TimeParam.new date_time
time_param.parser = parser
assert_equal DateTime.new('2012-12-12'), time_param.date_time
end
end
@tatey
Copy link
Author

tatey commented Nov 28, 2012

I suppose you could also set this up in the initialise, removing the extra noise of memoized readers.

def initialize value
  @parser = DateTime
  @value = value
end

@coop
Copy link

coop commented Nov 28, 2012

def initialize value, parser = DateTime
  @parser = parser
  @value = value
end

@tatey
Copy link
Author

tatey commented Nov 28, 2012

Yeah, I sometimes use that approach, but my preference is to only use it on instance methods, not the constructor. The reason being is when you change the order of arguments everything that instantiates this object breaks. By exposing it as an attribute then you at least get a consistent interface to it. The only time this would be useful if if you needed to access the dependancy from inside the constructor.

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