Class: Multimethod::Parameter
- Inherits:
-
Object
- Object
- Multimethod::Parameter
- Includes:
- Comparable
- Defined in:
- lib/multimethod/parameter.rb
Overview
Represents a Parameter in a Signature.
A Parameter has a name, type and position.
Parameters may also have a default value or may be a restarg, a parameter that collects all remaining arguments.
Restarg parameters have a lower score than other arguments.
Unlike Ruby parameters, Parameters are typed. Unspecified Parameter types default to Kernel.
Constant Summary collapse
- DEFAULT_SCORE_BASE =
The score base used for all Parameters with defaults.
200
- DEFAULT_SCORE =
The score used for all Parameters with defaults and no argument.
DEFAULT_SCORE_BASE + 100
- RESTARG_SCORE =
The score used for all restarg Parameters.
DEFAULT_SCORE + 100
Instance Attribute Summary collapse
-
#default ⇒ Object
The Parameter’s default value expression.
-
#i ⇒ Object
The Parameter’s offset in the Signature’s parameter list.
-
#name ⇒ Object
The Parameter name.
-
#restarg ⇒ Object
True if the Parameter is a restarg: e.g.: “*args”.
-
#signature ⇒ Object
The Parameter’s owning Signature.
-
#type ⇒ Object
The Paremeter’s type, defaults to Kernel.
-
#verbose ⇒ Object
Defines level of verbosity during processing.
Instance Method Summary collapse
-
#<=>(p) ⇒ Object
Compare two Parameters.
-
#all_types(arg_type) ⇒ Object
Returns a list of all parent Modules of an argument type, including itself, in most-specialized to least-specialized order.
-
#initialize(name = nil, type = nil, default = nil, restarg = false) ⇒ Parameter
constructor
Initialize a new Parameter.
-
#scan_string(str, need_names = true) ⇒ Object
Scan a string for a Parameter specification.
-
#score(arg) ⇒ Object
Returns the score of this Parameter matching an argument type.
-
#to_ruby_arg ⇒ Object
Return a String representing this Parameter as a Ruby method parameter.
-
#to_s ⇒ Object
Returns a String representing this Parameter in a Signature string.
-
#to_s_name ⇒ Object
Return a String representing this Parameter’s name.
-
#type_object ⇒ Object
Resolves type by name.
Constructor Details
#initialize(name = nil, type = nil, default = nil, restarg = false) ⇒ Parameter
Initialize a new Parameter.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/multimethod/parameter.rb', line 49 def initialize(name = nil, type = nil, default = nil, restarg = false) # $stderr.puts "initialize(#{name.inspect}, #{type}, #{default.inspect}, #{restarg.inspect})" if name # Default type if name is specified type ||= Kernel end @i = nil @type = type @default = default @restarg = restarg @verbose = false self.name = name # may affect @restarg @signature = nil end |
Instance Attribute Details
#default ⇒ Object
The Parameter’s default value expression.
37 38 39 |
# File 'lib/multimethod/parameter.rb', line 37 def default @default end |
#i ⇒ Object
The Parameter’s offset in the Signature’s parameter list. Parameter 0 is the implied “self” Parameter.
31 32 33 |
# File 'lib/multimethod/parameter.rb', line 31 def i @i end |
#name ⇒ Object
The Parameter name.
27 28 29 |
# File 'lib/multimethod/parameter.rb', line 27 def name @name end |
#restarg ⇒ Object
True if the Parameter is a restarg: e.g.: “*args”
40 41 42 |
# File 'lib/multimethod/parameter.rb', line 40 def restarg @restarg end |
#signature ⇒ Object
The Parameter’s owning Signature.
43 44 45 |
# File 'lib/multimethod/parameter.rb', line 43 def signature @signature end |
#type ⇒ Object
The Paremeter’s type, defaults to Kernel.
34 35 36 |
# File 'lib/multimethod/parameter.rb', line 34 def type @type end |
#verbose ⇒ Object
Defines level of verbosity during processing.
46 47 48 |
# File 'lib/multimethod/parameter.rb', line 46 def verbose @verbose end |
Instance Method Details
#<=>(p) ⇒ Object
Compare two Parameters. Only type and restarg are significant.
82 83 84 85 86 87 88 |
# File 'lib/multimethod/parameter.rb', line 82 def <=>(p) x = @type <=> p.type x = ! @restarg == ! p.restarg ? 0 : 1 if x == 0 x = ! @default == ! p.default ? 0 : 1 if x == 0 # $stderr.puts "#{to_s} <=> #{p.to_s} => #{x.inspect}" x end |
#all_types(arg_type) ⇒ Object
Returns a list of all parent Modules of an argument type, including itself, in most-specialized to least-specialized order.
193 194 195 |
# File 'lib/multimethod/parameter.rb', line 193 def all_types(arg_type) arg_type.ancestors end |
#scan_string(str, need_names = true) ⇒ Object
Scan a string for a Parameter specification.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/multimethod/parameter.rb', line 92 def scan_string(str, need_names = true) str.sub!(/\A\s+/, '') $stderr.puts " str=#{str.inspect}" if @verbose if md = /\A(\w+(::\w+)*)\s+(\w+)/s.match(str) # $stderr.puts " pre_match=#{md.pre_match.inspect}" # $stderr.puts " md[0]=#{md[0].inspect}" str = md.post_match type = md[1] name = md[3] elsif md = /\A(\*?\w+)/s.match(str) # $stderr.puts " pre_match=#{md.pre_match.inspect}" # $stderr.puts " md[0]=#{md[0].inspect}" str = md.post_match type = nil name = md[1] else raise NameError, "Syntax error in multimethod parameter: expected type and/or name at #{str.inspect}" end $stderr.puts " type=#{type.inspect}" if @verbose $stderr.puts " name=#{name.inspect}" if @verbose # Parse parameter default. if md = /\A\s*=\s*/.match(str) str = md.post_match in_paren = 0 default = '' until str.empty? # $stderr.puts " default: str=#{str.inspect}" # $stderr.puts " default: params=#{parameter_to_s}" if md = /\A(\s+)/s.match(str) str = md.post_match default = default + md[1] end if md = /\A("([^"\\]|\\.)*")/s.match(str) str = md.post_match default = default + md[1] elsif md = /\A('([^'\\]|\\.)*')/s.match(str) str = md.post_match default = default + md[1] elsif md = /\A(\()/.match(str) str = md.post_match in_paren = in_paren + 1 default = default + md[1] elsif in_paren > 0 && md = /\A(\))/s.match(str) str = md.post_match in_paren = in_paren - 1 default = default + md[1] elsif md = /\A(\))/s.match(str) break elsif in_paren == 0 && md = /\A,/s.match(str) break elsif md = /\A(\w+)/s.match(str) str = md.post_match default = default + md[1] elsif md = /\A(.)/s.match(str) str = md.post_match default = default + md[1] end end end self.name = name unless @name type ||= Kernel self.type = type unless @type self.default = default unless @default str end |
#score(arg) ⇒ Object
Returns the score of this Parameter matching an argument type.
The score is determined by the relative distance of the Parameter to the argument type. A lower distance means a tighter match of this Parameter.
Parameters with restargs or unspecfied default arguments score lower, see RESTARG_SCORE, DEFAULT_SCORE.
175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/multimethod/parameter.rb', line 175 def score(arg) if @restarg score = RESTARG_SCORE elsif @default && ! arg score = DEFAULT_SCORE else score = all_types(arg).index(type_object) end # $stderr.puts " score(#{signature.to_s}, #{to_s}, #{arg && arg.name}) => #{score}" score end |
#to_ruby_arg ⇒ Object
Return a String representing this Parameter as a Ruby method parameter.
217 218 219 |
# File 'lib/multimethod/parameter.rb', line 217 def to_ruby_arg "#{to_s_name}#{@default ? ' = ' + @default : ''}" end |
#to_s ⇒ Object
Returns a String representing this Parameter in a Signature string.
211 212 213 |
# File 'lib/multimethod/parameter.rb', line 211 def to_s "#{@type} #{to_ruby_arg}" end |
#to_s_name ⇒ Object
Return a String representing this Parameter’s name. Restargs will be prefixed with ‘*’.
224 225 226 |
# File 'lib/multimethod/parameter.rb', line 224 def to_s_name (@restarg ? "*" : '') + (@name.to_s || "_arg_#{@i}") end |