I'm trying to make a DSL like configuration for classes that include a module but to have the configured variable available to both class and instance methods seems to require littering the module with access methods. Is there a more elegant way to do this?
module DogMixin
class << self
def included(base)
base.extend ClassMethods
end
end
module ClassMethods
def breed(value)
@dog_breed = value
end
def dog_breed
@dog_breed
end
end
end
class Foo
include DogMixin
breed :havanese
end
puts Foo.dog_breed
# not implemented but should be able to do this as well
f = Foo.new
f.dog_breed
Your example is a bit weird I think :) Anyway, one way to avoid writing the accessors (the assignment - accessor is problematic in my eyes - especially in the given example) is to define constants, as in the example below. If however you need runtime-assignments, please edit your question (and thus render this answer invalid :) except you want to mess with runtime constant assignment, which is possible but messy).
module DogMixin
# **include** DogMixin to get `Class.dog_breed`
class << self
def included(base)
def base.dog_breed
self::DOG_BREED || "pug"
end
end
end
# **extend** DogMixin to get `instance.dog_breed`
def dog_breed
self.class.const_get(:DOG_BREED) || "pug"
end
end
class Foomer
DOG_BREED = 'foomer'
extend DogMixin
include DogMixin
end
f = Foomer.new
puts Foomer.dog_breed
puts f.dog_breed
# If I understand you correctly, this is the most important (?):
f.dog_breed == Foomer.dog_breed #=> true
It took some reading of (In Ruby) allowing mixed-in class methods access to class constants to get the Instance-And-Class Constant lookup from a module, but it works. I am not sure if I really like the solution though. Good question, although you could add a little detail.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments