Class: Multimethod::Parameter

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/multimethod/parameter.rb

Constant Summary collapse

RESTARG_SCORE =
9999

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = nil, type = nil, default = nil, restarg = false) ⇒ Parameter

Returns a new instance of Parameter.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/multimethod/parameter.rb', line 16

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

#defaultObject

Returns the value of attribute default.



10
11
12
# File 'lib/multimethod/parameter.rb', line 10

def default
  @default
end

#iObject

Returns the value of attribute i.



8
9
10
# File 'lib/multimethod/parameter.rb', line 8

def i
  @i
end

#nameObject

Returns the value of attribute name.



7
8
9
# File 'lib/multimethod/parameter.rb', line 7

def name
  @name
end

#restargObject

Returns the value of attribute restarg.



11
12
13
# File 'lib/multimethod/parameter.rb', line 11

def restarg
  @restarg
end

#signatureObject

Returns the value of attribute signature.



13
14
15
# File 'lib/multimethod/parameter.rb', line 13

def signature
  @signature
end

#typeObject

Returns the value of attribute type.



9
10
11
# File 'lib/multimethod/parameter.rb', line 9

def type
  @type
end

#verboseObject

Returns the value of attribute verbose.



14
15
16
# File 'lib/multimethod/parameter.rb', line 14

def verbose
  @verbose
end

Instance Method Details

#<=>(p) ⇒ Object



48
49
50
51
52
53
54
# File 'lib/multimethod/parameter.rb', line 48

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) ⇒ Object



139
140
141
# File 'lib/multimethod/parameter.rb', line 139

def all_types(arg)
  arg.ancestors
end

#scan_string(str, need_names = true) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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
# File 'lib/multimethod/parameter.rb', line 57

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



133
134
135
136
# File 'lib/multimethod/parameter.rb', line 133

def score(arg)
  return RESTARG_SCORE if @restarg
  score = all_types(arg).index(type_object)
end

#to_ruby_argObject



160
161
162
# File 'lib/multimethod/parameter.rb', line 160

def to_ruby_arg
  "#{to_s_name}#{@default ? ' = ' + @default : ''}"
end

#to_sObject



155
156
157
# File 'lib/multimethod/parameter.rb', line 155

def to_s
  "#{@type} #{to_ruby_arg}"
end

#to_s_nameObject



165
166
167
# File 'lib/multimethod/parameter.rb', line 165

def to_s_name
  (@restarg ? "*" : '') + (@name.to_s || "_arg_#{@i}")
end

#type_objectObject



144
145
146
147
148
149
150
151
152
# File 'lib/multimethod/parameter.rb', line 144

def type_object
  if @type.kind_of?(String)
    @type = Table.instance.name_to_object(@type, 
                                          @signature.mod, 
                                          @signature.file, 
                                          @signature.line)
  end
  @type
end