lib/tins/method_description.rb
module Tins
module MethodDescription
class Parameters
class Parameter < Struct.new(:type, :name)
def ==(other)
type == other.type
end
def inspect
"#<#{self.class} #{to_s.inspect}>"
end
end
class RestParameter < Parameter
def to_s
"*#{name}"
end
end
class KeyrestParameter < Parameter
def to_s
"**#{name}"
end
end
class ReqParameter < Parameter
def to_s
name.to_s
end
end
class OptParameter < Parameter
def to_s
"#{name}=?"
end
end
class KeyParameter < Parameter
def to_s
"#{name}:?"
end
end
class KeyreqParameter < Parameter
def to_s
"#{name}:"
end
end
class BlockParameter < Parameter
def to_s
"&#{name}"
end
end
class GenericParameter < Parameter
def to_s
[ name, type ] * ?:
end
end
def self.build(type, name)
parameter_classname = "#{type.to_s.capitalize}Parameter"
parameter_class =
if const_defined? parameter_classname
const_get parameter_classname
else
GenericParameter
end
parameter_class.new(type, name)
end
end
class Signature
def initialize(*parameters)
@parameters = parameters
end
attr_reader :parameters
def eql?(other)
@parameters.eql? other.parameters
end
def ==(other)
@parameters == other.parameters
end
def ===(method)
self == method.signature
end
def to_s
@parameters * ?,
end
def inspect
"#<#{self.class} (#{to_s})>"
end
end
def signature
description style: :parameters
end
def description(style: :namespace)
valid_styles = %i[ namespace name parameters ]
valid_styles.include?(style) or
raise ArgumentError,
"style has to be one of #{valid_styles * ', '}"
if respond_to?(:parameters)
generated_name = 'x0'
parameter_array = parameters.map { |p_type, p_name|
unless p_name
generated_name = generated_name.succ
p_name = generated_name
end
Parameters.build(p_type, p_name)
}
signature = Signature.new(*parameter_array)
if style == :parameters
return signature
end
end
result = ''
if style == :namespace
if owner <= Module
result << receiver.to_s << ?. # XXX Better to use owner here as well?
else
result << owner.name.to_s << ?#
end
end
if %i[ namespace name ].include?(style)
result << name.to_s << '('
end
result << (signature || arity).to_s
if %i[ namespace name ].include?(style)
result << ?)
end
result
end
end
end