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
- @@debug =
nil
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.
Class Method Summary collapse
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 name.
Constructor Details
#initialize(name = nil, type = nil, default = nil, restarg = false) ⇒ Parameter
Initialize a new Parameter.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/multimethod/parameter.rb', line 54 def initialize(name = nil, type = nil, default = nil, restarg = false) # $stderr.puts "initialize(#{name.inspect}, #{type}, #{default.inspect}, #{restarg.inspect})" @i = nil @type = type @type_object = nil @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.
42 43 44 |
# File 'lib/multimethod/parameter.rb', line 42 def default @default end |
#i ⇒ Object
The Parameter’s offset in the Signature’s parameter list. Parameter 0 is the implied “self” Parameter.
36 37 38 |
# File 'lib/multimethod/parameter.rb', line 36 def i @i end |
#name ⇒ Object
The Parameter name.
32 33 34 |
# File 'lib/multimethod/parameter.rb', line 32 def name @name end |
#restarg ⇒ Object
True if the Parameter is a restarg: e.g.: “*args”
45 46 47 |
# File 'lib/multimethod/parameter.rb', line 45 def restarg @restarg end |
#signature ⇒ Object
The Parameter’s owning Signature.
48 49 50 |
# File 'lib/multimethod/parameter.rb', line 48 def signature @signature end |
#type ⇒ Object
The Paremeter’s type, defaults to Kernel.
39 40 41 |
# File 'lib/multimethod/parameter.rb', line 39 def type @type end |
#verbose ⇒ Object
Defines level of verbosity during processing.
51 52 53 |
# File 'lib/multimethod/parameter.rb', line 51 def verbose @verbose end |
Class Method Details
.debug=(x) ⇒ Object
18 19 20 |
# File 'lib/multimethod/parameter.rb', line 18 def self.debug=(x) @@debug = x end |
Instance Method Details
#<=>(p) ⇒ Object
Compare two Parameters. Parameter name is insignificant.
85 86 87 88 89 90 91 |
# File 'lib/multimethod/parameter.rb', line 85 def <=>(p) x = type_object <=> p.type_object 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.
207 208 209 |
# File 'lib/multimethod/parameter.rb', line 207 def all_types(arg_type) arg_type.ancestors end |
#scan_string(str, need_names = true) ⇒ Object
Scan a string for a Parameter specification.
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 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/multimethod/parameter.rb', line 95 def scan_string(str, need_names = true) # @verbose ||= @@debug type = nil name = nil default = nil 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 $stderr.puts " default=#{default.inspect}" if @verbose end end self.name = name unless @name self.type = type unless @type default = nil if default && default.empty? 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.
If arg
is nil, this Parameter is being matched as a restarg or a parameter default.
Parameters with restargs or unspecfied default arguments score lower, see RESTARG_SCORE, DEFAULT_SCORE.
189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/multimethod/parameter.rb', line 189 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.
240 241 242 |
# File 'lib/multimethod/parameter.rb', line 240 def to_ruby_arg "#{to_s_name}#{@default ? ' = ' + @default : ''}" end |
#to_s ⇒ Object
Returns a String representing this Parameter in a Signature string.
234 235 236 |
# File 'lib/multimethod/parameter.rb', line 234 def to_s "#{@type}#{@type ? ' ' : ''}#{to_ruby_arg}" end |
#to_s_name ⇒ Object
Return a String representing this Parameter’s name. Restargs will be prefixed with ‘*’.
247 248 249 |
# File 'lib/multimethod/parameter.rb', line 247 def to_s_name (@restarg ? "*" : '') + (@name.to_s || "_arg_#{@i}") end |
#type_object ⇒ Object
Resolves type name
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/multimethod/parameter.rb', line 213 def type_object unless @type_object case @type when String @type_object = Table.instance.name_to_object(@type, @signature && @signature.mod, @signature && @signature.file, @signature && @signature.line) when Module @type_object = @type when NilClass @type_object = Kernel else raise("Incorrect parameter type #{@type.inspect}") end end @type_object end |