Created
February 20, 2012 00:51
-
-
Save capnslipp/1866858 to your computer and use it in GitHub Desktop.
Stack Overflow Question #5390537 (http://stackoverflow.com/questions/5390537)
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
## encoding: utf-8 | |
## Alex D's solution (1st revision) to http://stackoverflow.com/questions/5390537/best-practices-and-implementation-for-macro-and-class-level-accessor-methods/9019388#9019388 | |
module MacroMethods | |
private | |
def full_name(full_name) | |
# non-trivial, one-time-only set-up code exists here in actual usage | |
self.class_eval { const_set :FULL_NAME, full_name.to_s } | |
# this method can only be called once in the definition of any given class, | |
# because after the first call, it will be redefined! | |
extend AccessorMethods | |
end | |
end | |
module AccessorMethods | |
public | |
def full_name | |
# a non-trivial, runtime-calculated value is returned here in actual usage | |
self::FULL_NAME.upcase | |
end | |
end | |
class Base | |
extend MacroMethods | |
end | |
class Something < Base | |
full_name 'after this call, I will get a new full_name method!' | |
end | |
class SomethingElse < Base | |
full_name 'so will I!' | |
end | |
puts "Something.full_name: #{Something.full_name}" | |
puts "SomethingElse.full_name: #{SomethingElse.full_name}" |
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
## encoding: utf-8 | |
## Alex D's solution (2nd revision) to http://stackoverflow.com/questions/5390537/best-practices-and-implementation-for-macro-and-class-level-accessor-methods/9019388#9019388 | |
module MacroMethods | |
private | |
def full_name(full_name) | |
# non-trivial, one-time-only set-up code exists here in actual usage | |
self.class_eval { const_set :FULL_NAME, full_name.to_s } | |
# this method can only be called once in the definition of any given class, | |
# because after the first call, it will be redefined! | |
define_method(:full_name) do | |
# a non-trivial, runtime-calculated value is returned here in actual usage | |
self.class.class_eval { self::FULL_NAME.upcase } | |
end | |
end | |
end | |
class Base | |
extend MacroMethods | |
end | |
class Something < Base | |
full_name 'after this call, I will get a new full_name method!' | |
end | |
class SomethingElse < Base | |
full_name 'so will I!' | |
end | |
puts "Something.new.full_name: #{Something.new.full_name}" | |
puts "SomethingElse.new.full_name: #{SomethingElse.new.full_name}" |
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
## encoding: utf-8 | |
## Modification of Alex D's solution to http://stackoverflow.com/questions/5390537/best-practices-and-implementation-for-macro-and-class-level-accessor-methods/9019388#9019388 | |
module MacroMethods | |
private | |
def full_name(full_name) | |
# non-trivial, one-time-only set-up code exists here in actual usage | |
self.class_eval { const_set :FULL_NAME, full_name.to_s } | |
# this method can only be called once in the definition of any given class, | |
# because after the first call, it will be redefined! | |
self.singleton_class.instance_eval { | |
undef_method(:full_name) | |
define_method(:full_name) do | |
# a non-trivial, runtime-calculated value is returned here in actual usage | |
self::FULL_NAME.upcase | |
end | |
public :full_name | |
} | |
define_method(:full_name) do | |
# a non-trivial, runtime-calculated value is returned here in actual usage | |
self.class.class_eval { self::FULL_NAME.upcase } | |
end | |
end | |
end | |
class Base | |
extend MacroMethods | |
end | |
class Something < Base | |
full_name 'after this call, I will get a new full_name method!' | |
end | |
class SomethingElse < Base | |
full_name 'so will I!' | |
end | |
puts "Something.new.full_name: #{Something.new.full_name}" | |
puts "SomethingElse.new.full_name: #{SomethingElse.new.full_name}" | |
puts "Something.full_name: #{Something.full_name}" | |
puts "SomethingElse.full_name: #{SomethingElse.full_name}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment