Module: SY::ExpressibleInUnits
- Included in:
- Magnitude
- Defined in:
- lib/sy/expressible_in_units.rb
Overview
This mixin provides ability to respond to SY unit symbol methods.
Defined Under Namespace
Modules: DetectRedefine
Constant Summary collapse
- COLLISION_WARNING =
"Unit %s collision, method already defined on %s!"- REDEFINE_WARNING =
"Method %s being defined on %s shadows SY unit method!"- RecursionError =
Class.new StandardError
Class Method Summary collapse
-
.exponentiation_string(exp) ⇒ Object
Return exponentiation string (suffix) or empty ς if not necessary.
-
.find_unit(ς) ⇒ Object
Find unit based on name / abbreviation.
-
.included(receiver) ⇒ Object
#included hook of this module is set to perfom a casual check for blatant name collisions between SY::Unit-implied methods, and existing methods of the include receiver.
-
.included_in ⇒ Object
Modules in which this mixin has been included.
-
.known_units ⇒ Object
Currently defined unit instances, if any.
-
.method_family ⇒ Object
All methods defined by this mixin.
-
.prefix_method_string(prefix) ⇒ Object
Return prefix method or empty string, if prefix method not necessary.
-
.unit_namespace ⇒ Object
Unit namespace.
Instance Method Summary collapse
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(ß, *args, &block) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/sy/expressible_in_units.rb', line 123 def method_missing ß, *args, &block return self if ß.to_s =~ /begin|end/ # 3rd party bug workaround super if ß.to_s =~ /to_.+/ # dissmiss :to_..., esp. :to_ary begin # prevent recurrent call of method_missing for the same symbol anti_recursion_exec token: ß, var: :@SY_Units_mmiss do puts "Method missing: '#{ß}'" if SY::DEBUG prefixes, units, exps = parse_unit_symbol ß # Define the unit method on self.class: # I'D HAVE TO PERFORM THE COLLISION CHECK HERE # IF NO COLLISION, INFORM THE SUBSEQUENT METHOD DEFINED CALL ON # SELF.CLASS puts "parsed" if SY::DEBUG self.class.instance_variable_set "@no_collision", ß # FIXME: This is too clumsy self.class.module_eval write_unit_method( ß, prefixes, units, exps ) SY::ExpressibleInUnits.method_family << self.class.instance_method( ß ) end rescue NameError => err puts "NameError raised: #{err}" if SY::DEBUG super # give up rescue SY::ExpressibleInUnits::RecursionError super # give up else # actually invoke the method that we just defined send ß, *args, &block end end |
Class Method Details
.exponentiation_string(exp) ⇒ Object
Return exponentiation string (suffix) or empty ς if not necessary.
118 119 120 |
# File 'lib/sy/expressible_in_units.rb', line 118 def exponentiation_string exp exp == 1 ? '' : " ** #{exp}" end |
.find_unit(ς) ⇒ Object
Find unit based on name / abbreviation.
99 100 101 102 103 104 105 106 |
# File 'lib/sy/expressible_in_units.rb', line 99 def find_unit ς puts "searching for unit #{ς}" if SY::DEBUG known_units.find do |u| u.name.to_s.downcase == ς.downcase && ( ς == ς.downcase || ς == ς.upcase ) || u.short.to_s == ς end end |
.included(receiver) ⇒ Object
#included hook of this module is set to perfom a casual check for blatant name collisions between SY::Unit-implied methods, and existing methods of the include receiver.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/sy/expressible_in_units.rb', line 48 def included receiver included_in << receiver # keep track of where the mixin has been included # Warn if the receiver has potentially colliding methods. inst_methods = receiver.instance_methods w = COLLISION_WARNING % ["%s", receiver] known_units.each do |unit| next unless unit.warns? name, short = unit.name, unit.abbreviation warn w % "name method ##{name}" if inst_methods.include? name warn w % "abbreviation method ##{short}" if inst_methods.include? short end # Warn if shadowing methods are defined on the receiver later. if receiver.is_a? Class receiver.extend ::SY::ExpressibleInUnits::DetectRedefine end end |
.included_in ⇒ Object
Modules in which this mixin has been included.
67 68 69 |
# File 'lib/sy/expressible_in_units.rb', line 67 def included_in @included_in ||= [] end |
.known_units ⇒ Object
Currently defined unit instances, if any.
82 83 84 85 86 87 88 89 |
# File 'lib/sy/expressible_in_units.rb', line 82 def known_units begin unit_namespace.instances rescue NoMethodError [] # no #instances method defined yet end .tap { |r| puts "Known units are #{r}" if SY::DEBUG } end |
.method_family ⇒ Object
All methods defined by this mixin.
93 94 95 |
# File 'lib/sy/expressible_in_units.rb', line 93 def method_family @method_family ||= [] end |
.prefix_method_string(prefix) ⇒ Object
Return prefix method or empty string, if prefix method not necessary.
110 111 112 113 114 |
# File 'lib/sy/expressible_in_units.rb', line 110 def prefix_method_string prefix puts "About to call PREFIX TABLE.to_full with #{prefix}" if SY::DEBUG full_prefix = SY::PREFIX_TABLE.to_full( prefix ) full_prefix == '' ? '' : ".#{full_prefix}" end |
Instance Method Details
#respond_to_missing?(ß, *args, &block) ⇒ Boolean
149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/sy/expressible_in_units.rb', line 149 def respond_to_missing? ß, *args, &block # dismiss :to_... methods and /begin|end/ (3rd party bug workaround) return false if ß.to_s =~ /to_.+|begin|end/ !! begin anti_recursion_exec token: ß, var: :@SY_Units_rmiss do parse_unit_symbol ß end rescue NameError, SY::ExpressibleInUnits::RecursionError false else true end end |