Created
February 28, 2015 15:31
-
-
Save tylerhunt/462bde72ae2b681b4e36 to your computer and use it in GitHub Desktop.
A macro to allow object dependencies to be specified at the class level with a block defining a default value. Based on attr_defaultable.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Dependencies | |
# Ensure dependencies from the superclass are inherited by the subclass. | |
def inherited(subclass) | |
if superclass.respond_to?(:dependencies) | |
subclass.dependencies.concat dependencies | |
end | |
super | |
end | |
# Stores a list of dependency attributes for use by the initializer. | |
def dependencies | |
@dependencies ||= [] | |
end | |
# Defines a new dependency attribute with a default value. | |
def dependency(attribute, default) | |
# Define a getter that lazily sets a default value. | |
define_method attribute do | |
if instance_variable_defined?(:"@#{attribute}") | |
instance_variable_get(:"@#{attribute}") | |
else | |
instance_variable_set(:"@#{attribute}", default.call) | |
end | |
end | |
# Define a setter that lazily sets a default value. | |
attr_writer attribute | |
# Mark the getter and setter as protected. | |
protected attribute, "#{attribute}=" | |
# Add the attribute to the list of dependencies. | |
dependencies << attribute | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'dependencies' | |
class Example | |
extend Dependencies | |
dependency :value, -> { :default } | |
end | |
class ExtendedExample < Example | |
dependency :another_value, -> { :another_default } | |
end | |
example = ExtendedExample.new | |
example.send(:value) # => :default | |
example.send(:another_value) # => :another_default |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment