Created
August 10, 2012 17:16
-
-
Save isaacsanders/3315843 to your computer and use it in GitHub Desktop.
Do you prefer metaprogramming, or lots of repetition?
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 'chemistry/temperature' | |
module Chemistry | |
class Element | |
class << self | |
def property(name, type, &transformer) | |
define_property_setter name, type, &transformer | |
define_property_getter name | |
end | |
def define_property_setter name, type, &transformer | |
define_class_method name do |value| | |
value = transformer.call value if block_given? | |
if value.is_a? type | |
const_set name.to_s.upcase, value | |
else | |
raise TypeError, "can't convert #{value.class} into #{type}" | |
end | |
end | |
end | |
def define_class_method name, &definition | |
class_methods = Module.new | |
class_methods.instance_eval do | |
define_method name, &definition | |
end | |
extend class_methods | |
end | |
def define_property_getter name | |
define_method name do | |
self.class.const_get name.to_s.upcase | |
end | |
end | |
def temperature_property(name) | |
property name, Chemistry::Temperature::Unit do |value| | |
Chemistry::Temperature.parse value | |
end | |
end | |
end | |
property :symbol, String | |
property :atomic_number, Integer | |
property :atomic_weight, Numeric | |
temperature_property :melting_point | |
temperature_property :boiling_point | |
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
module Chemistry | |
class Element | |
class << self | |
def symbol symbol | |
if symbol.is_a? String | |
const_set :SYMBOL, symbol | |
else | |
raise TypeError, "can't convert #{symbol.class} into String" | |
end | |
end | |
def atomic_number atomic_number | |
if atomic_number.is_a? Integer | |
const_set :ATOMIC_NUMBER, atomic_number | |
else | |
raise TypeError, "can't convert #{atomic_number.class} into Integer" | |
end | |
end | |
def atomic_weight atomic_weight | |
if atomic_weight.is_a? Numeric | |
const_set :ATOMIC_WEIGHT, atomic_weight | |
else | |
raise TypeError, "can't convert #{atomic_weight.class} into Numeric" | |
end | |
end | |
end | |
def symbol | |
self.class::SYMBOL | |
end | |
def atomic_number | |
self.class::ATOMIC_NUMBER | |
end | |
def atomic_weight | |
self.class::ATOMIC_WEIGHT | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment