platypus 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY +19 -0
- data/LICENSE +22 -0
- data/NOTES.rdoc +6 -0
- data/PROFILE +24 -0
- data/README +94 -0
- data/REQUIRE +6 -0
- data/VERSION +5 -0
- data/lib/platypus.rb +4 -0
- data/lib/platypus/core_ext.rb +8 -0
- data/lib/platypus/overload.rb +98 -0
- data/lib/platypus/type.rb +153 -0
- data/lib/platypus/typecast.rb +57 -0
- data/test/test_overload.rb +173 -0
- metadata +78 -0
data/HISTORY
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
= Change History
|
|
2
|
+
|
|
3
|
+
# == History
|
|
4
|
+
#
|
|
5
|
+
# * 2006-06-06 3v1l_d4y:
|
|
6
|
+
# * Removed transformation options.
|
|
7
|
+
# * Removed StringIO typecast. It is not required by default.
|
|
8
|
+
# * Added TypeCastException for better error reporting while coding.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
== 1.0.0 // 2009-07-07
|
|
12
|
+
|
|
13
|
+
This is the initial stand-alone release of TypeCast,
|
|
14
|
+
spun-off from Ruby Facets.
|
|
15
|
+
|
|
16
|
+
* 1 Major Enhancement
|
|
17
|
+
|
|
18
|
+
* Happy Birthday!
|
|
19
|
+
|
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2010 Thomas Sawyer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
22
|
+
|
data/NOTES.rdoc
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
= Developer's Notes
|
|
2
|
+
|
|
3
|
+
== 2010-05-27 | Alias for +Overloadable#overload+
|
|
4
|
+
|
|
5
|
+
I am not sure if I like +con+, +sig+ or +over+ better as a short alias for +overload+. I thought of +con+ becuase of it's double meaning as Latin for 'with' and as an abbreviation for 'conditional'. But it seems esoteric in practice, perhaps b/c it would be too general a term if we were programming in Spanish. While +over+ probably makes the most sense in terms of being an abbreviated form of +overload+, +sig+ is the same number of characters as +def+ and conveys some additional semantics which applies to method overloading --the *signature*.
|
|
6
|
+
|
data/PROFILE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
title : Platypus
|
|
3
|
+
suite : rubyworks
|
|
4
|
+
summary: Type Casting System
|
|
5
|
+
license: MIT
|
|
6
|
+
created: 2004-01-01
|
|
7
|
+
|
|
8
|
+
copyright:
|
|
9
|
+
Copyright (c) 2004 Thomas Sawyer
|
|
10
|
+
|
|
11
|
+
authors:
|
|
12
|
+
- Thomas Sawyer
|
|
13
|
+
- Jonas Pfenniger
|
|
14
|
+
|
|
15
|
+
description:
|
|
16
|
+
Provides a complete double-dispatch type conversion system,
|
|
17
|
+
method overloadability and psuedo-classes.
|
|
18
|
+
|
|
19
|
+
resources:
|
|
20
|
+
homepage: http://rubyworks.github.com/platypus
|
|
21
|
+
development: http://github.com/rubyworks/platypus
|
|
22
|
+
repository: http://rubyworks.github.com/platypus.git
|
|
23
|
+
forum: http://googlegroups/group/rubyworks-mailinglist
|
|
24
|
+
|
data/README
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
= Platypus
|
|
2
|
+
_ ___
|
|
3
|
+
/ \ / \
|
|
4
|
+
\. |: cc|
|
|
5
|
+
(.|:,---,
|
|
6
|
+
(.|: \ c|
|
|
7
|
+
(. y-'
|
|
8
|
+
\ _ /
|
|
9
|
+
m m
|
|
10
|
+
|
|
11
|
+
* home: http://rubyworks.github.com/platypus
|
|
12
|
+
* work: http://github.com/rubyworks/platypus
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
== DESCRIPTION
|
|
16
|
+
|
|
17
|
+
Platypus provides a generalized type conversion system,
|
|
18
|
+
method overloading and psuedo-classes.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
== RELEASE NOTES
|
|
22
|
+
|
|
23
|
+
Please see HISTORY file.
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
== SYNOPSIS
|
|
27
|
+
|
|
28
|
+
=== Type Conversion
|
|
29
|
+
|
|
30
|
+
"1234".to(Float) => 1234.0 (Float)
|
|
31
|
+
|
|
32
|
+
Time.from("6:30") => 1234.0 (Time)
|
|
33
|
+
|
|
34
|
+
=== Method Overloading
|
|
35
|
+
|
|
36
|
+
To overload a method use the #overload method to define
|
|
37
|
+
new functionality based on a specified type interface.
|
|
38
|
+
|
|
39
|
+
class X
|
|
40
|
+
include Overloadable
|
|
41
|
+
|
|
42
|
+
def x
|
|
43
|
+
"hello"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
sig Integer
|
|
47
|
+
|
|
48
|
+
def x(i)
|
|
49
|
+
i
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
sig String, String
|
|
53
|
+
|
|
54
|
+
def x(s1, s2)
|
|
55
|
+
[s1, s2]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
=== Psuedo-Classes
|
|
60
|
+
|
|
61
|
+
class KiloType < Type
|
|
62
|
+
x % 1000 == 0
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
KiloType === 1000
|
|
66
|
+
KiloType === 2000
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
== INSTALLATION
|
|
70
|
+
|
|
71
|
+
To install with RubyGems simply open a console and type:
|
|
72
|
+
|
|
73
|
+
$ gem install typecast
|
|
74
|
+
|
|
75
|
+
Site installation can be achieved with Setup.rb (gem install setup),
|
|
76
|
+
then download the tarball package and type:
|
|
77
|
+
|
|
78
|
+
$ tar -xvzf typecast-1.0.0.tgz
|
|
79
|
+
$ cd typecast-1.0.0
|
|
80
|
+
$ sudo setup.rb all
|
|
81
|
+
|
|
82
|
+
Windows users use 'ruby setup.rb all'.
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
== COPYING
|
|
86
|
+
|
|
87
|
+
Copyright (c) 2010 Thomas Sawyer
|
|
88
|
+
|
|
89
|
+
This program is ditributed unser the terms of the Ruby license.
|
|
90
|
+
|
|
91
|
+
See LICENSE or COPYING file for details.
|
|
92
|
+
|
|
93
|
+
#--
|
|
94
|
+
*-* mode: rdoc *-*
|
data/REQUIRE
ADDED
data/VERSION
ADDED
data/lib/platypus.rb
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# The Obverloadable mixin allows you to easily
|
|
2
|
+
# overload methods based on method signitures.
|
|
3
|
+
#
|
|
4
|
+
module Overloadable
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
def self.append_features(base)
|
|
8
|
+
if Module==base
|
|
9
|
+
super(base)
|
|
10
|
+
else
|
|
11
|
+
base.extend(self)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Setup an overload state.
|
|
16
|
+
def overload(*signature)
|
|
17
|
+
(@overload_stack ||= []) << signature
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Short alias for +overload+.
|
|
21
|
+
alias_method :sig, :overload
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
def method_added(name)
|
|
25
|
+
return if $skip
|
|
26
|
+
|
|
27
|
+
@overload_stack ||= []
|
|
28
|
+
@overload_method ||= {}
|
|
29
|
+
|
|
30
|
+
signature = @overload_stack.pop
|
|
31
|
+
|
|
32
|
+
if !method_defined?("#{name}:origin")
|
|
33
|
+
$skip = true
|
|
34
|
+
if signature
|
|
35
|
+
define_method("#{name}:origin"){|*a| raise ArgumentError }
|
|
36
|
+
else
|
|
37
|
+
alias_method("#{name}:origin", name)
|
|
38
|
+
end
|
|
39
|
+
$skip = false
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
if signature
|
|
43
|
+
@overload_module ||= Module.new
|
|
44
|
+
|
|
45
|
+
include @overload_module
|
|
46
|
+
|
|
47
|
+
signature = Signature[*signature]
|
|
48
|
+
@overload_method[name] ||= []
|
|
49
|
+
@overload_method[name] << signature
|
|
50
|
+
|
|
51
|
+
signame = "#{name}:#{signature.key}"
|
|
52
|
+
|
|
53
|
+
alias_method(signame, name)
|
|
54
|
+
|
|
55
|
+
sigs = @overload_method[name]
|
|
56
|
+
$skip = true
|
|
57
|
+
define_method(name) do |*args|
|
|
58
|
+
#sigs.sort.each do |sig|
|
|
59
|
+
s = sigs.find{ |sig| sig.match?(args) }
|
|
60
|
+
if s
|
|
61
|
+
__send__("#{name}:#{s.key}", *args)
|
|
62
|
+
else
|
|
63
|
+
__send__("#{name}:origin", *args)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
$skip = false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
#
|
|
72
|
+
class Signature < Array
|
|
73
|
+
def key
|
|
74
|
+
hash #Marshal.dump(self)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
def match?(args)
|
|
79
|
+
return false unless size == args.size
|
|
80
|
+
size.times do |i|
|
|
81
|
+
return false unless self[i] === args[i]
|
|
82
|
+
end
|
|
83
|
+
true
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
def <=>(other)
|
|
88
|
+
cmp = (size <=> other.size)
|
|
89
|
+
return cmp if cmp && cmp != 0
|
|
90
|
+
size.times do |i|
|
|
91
|
+
cmp = (self[i] <=> other[i])
|
|
92
|
+
return cmp if cmp && cmp != 0
|
|
93
|
+
end
|
|
94
|
+
0
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
require 'platypus/core_ext'
|
|
2
|
+
|
|
3
|
+
# Base class for Euphoria-like Types.
|
|
4
|
+
#
|
|
5
|
+
# class KiloType < Type
|
|
6
|
+
# condition do |x|
|
|
7
|
+
# x.case? Integer
|
|
8
|
+
# x.kind_of?(Integer)
|
|
9
|
+
# x.respond_to?(:succ)
|
|
10
|
+
# x > 1000
|
|
11
|
+
# end
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
# Becuase the +x.something?+ is so common, TypeCast provides
|
|
15
|
+
# special "magic-dot" method to make defining these
|
|
16
|
+
# conditions more concise.
|
|
17
|
+
#
|
|
18
|
+
# class KiloType < Type
|
|
19
|
+
# x.case? Integer
|
|
20
|
+
# x.kind_of?(Integer)
|
|
21
|
+
# x.respond_to?(:succ)
|
|
22
|
+
# x > 1000
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# While TypeCasts are not actual types in the sense they
|
|
26
|
+
# are not actual classes. They can be used for conversion
|
|
27
|
+
# by defining a "from_{class}" class method. In doing so
|
|
28
|
+
# you should make sure the result of the conversion conforms
|
|
29
|
+
# to the typecast. You can use the TypeCast.validate method
|
|
30
|
+
# to make that a bit easier. For instance:
|
|
31
|
+
#
|
|
32
|
+
# class KiloType
|
|
33
|
+
# def from_string(str)
|
|
34
|
+
# validate(str.to_i)
|
|
35
|
+
# end
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# TypeCast also provides a helper DSL method that handles
|
|
39
|
+
# this for you.
|
|
40
|
+
#
|
|
41
|
+
# class KiloType
|
|
42
|
+
# conversion String do |str|
|
|
43
|
+
# str.to_i
|
|
44
|
+
# end
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# This will define a method equivalent to the prior example.
|
|
48
|
+
|
|
49
|
+
class Type
|
|
50
|
+
|
|
51
|
+
# Activeate/Deactivate type-checking globally (NOT USED YET).
|
|
52
|
+
def self.check(on_or_off=nil)
|
|
53
|
+
@check = on_or_off unless on_or_off.nil?
|
|
54
|
+
@check
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.validate(obj)
|
|
58
|
+
raise TypeError unless self === obj
|
|
59
|
+
return obj
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
def self.condition(&block)
|
|
64
|
+
@index ||= index
|
|
65
|
+
@index = @index.succ
|
|
66
|
+
define_method("condition_#{@index}", &block)
|
|
67
|
+
#@conditions << block
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
def self.conversion(klass, &block)
|
|
72
|
+
name = klass.name.downcase.gsub('::', '_')
|
|
73
|
+
(class << self; self; end).class_eval do
|
|
74
|
+
define_method("from_#{name}") do |from|
|
|
75
|
+
r = block.call(from)
|
|
76
|
+
validate(r)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
def self.x
|
|
83
|
+
@x ||= Conditions.new(self)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
class Conditions
|
|
88
|
+
instance_methods.each{ |x| private x unless x.to_s =~ /^__/ }
|
|
89
|
+
|
|
90
|
+
def initialize(type)
|
|
91
|
+
@type = type
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
#def __conditions__
|
|
95
|
+
# @__conditions__ ||= []
|
|
96
|
+
#end
|
|
97
|
+
|
|
98
|
+
def method_missing(s, *a, &b)
|
|
99
|
+
@type.condition do |x|
|
|
100
|
+
x.__send__(s, *a, &b)
|
|
101
|
+
end
|
|
102
|
+
#__conditions__ << [s, a, b]
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
#
|
|
107
|
+
#def initialize(*matchers, &validate)
|
|
108
|
+
# @matchers = matchers
|
|
109
|
+
# @validate = validate
|
|
110
|
+
#end
|
|
111
|
+
|
|
112
|
+
#
|
|
113
|
+
def self.index
|
|
114
|
+
methods = instance_methods.select{ |m| m.to_s =~ /^condition_/ }
|
|
115
|
+
indexes = methods.map{ |m| m.split('_')[1].to_i }
|
|
116
|
+
indexes.max || 0
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def self.conditions
|
|
120
|
+
#x.__conditions__ + (@conditions || []) + (defined?(super) ? super : [])
|
|
121
|
+
instance_methods.select{ |m| m.to_s =~ /^condition_/ }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
#
|
|
125
|
+
def self.===(obj)
|
|
126
|
+
#conditions.all? do |s, a, b|
|
|
127
|
+
# obj.__send__(s, *a, &b)
|
|
128
|
+
#end
|
|
129
|
+
instance = new
|
|
130
|
+
conditions.all? do |method|
|
|
131
|
+
instance.__send__(method, obj)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
#
|
|
136
|
+
#def match?(argument)
|
|
137
|
+
# @matchers.all? do |matcher|
|
|
138
|
+
# case matcher
|
|
139
|
+
# when Symbol
|
|
140
|
+
# argument.send(:respond_to?, matcher) }
|
|
141
|
+
# else
|
|
142
|
+
# matcher === argument
|
|
143
|
+
# end
|
|
144
|
+
# end
|
|
145
|
+
#end
|
|
146
|
+
|
|
147
|
+
#
|
|
148
|
+
#def valid?(obj)
|
|
149
|
+
# @validate[obj] if @validate
|
|
150
|
+
#end
|
|
151
|
+
|
|
152
|
+
end
|
|
153
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
|
|
3
|
+
class Class
|
|
4
|
+
|
|
5
|
+
def typecasts
|
|
6
|
+
@typecasts ||= {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Define a type cast.
|
|
10
|
+
def typecast(target_class, *specifics, &block)
|
|
11
|
+
set = (specifics.empty? ? nil : Set.new(specifics))
|
|
12
|
+
typecasts[target_class] ||= {}
|
|
13
|
+
typecasts[target_class][set] = block
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Convert +source+ to an instance of the class.
|
|
17
|
+
def from(source, specifics={})
|
|
18
|
+
set = (specifics.empty? ? nil : Set.new(specifics.keys))
|
|
19
|
+
base = ancestors.find{ |anc| source.class.typecasts.key?(anc) }
|
|
20
|
+
if base
|
|
21
|
+
cast = source.class.typecasts[base]
|
|
22
|
+
if block = cast[set]
|
|
23
|
+
if block.arity == 1
|
|
24
|
+
return block.call(source)
|
|
25
|
+
else
|
|
26
|
+
return block.call(source, specifics)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
raise TypeError
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Object
|
|
37
|
+
# Convert an object to an instance of given +target_class+.
|
|
38
|
+
def to(target_class, specifics={})
|
|
39
|
+
target_class.from(self, specifics)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class String #:nodoc:
|
|
45
|
+
typecast Integer do |string|
|
|
46
|
+
Integer(string)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class Time #:nodoc:
|
|
51
|
+
# This method will require the 'time.rb' Time extensions.
|
|
52
|
+
typecast String do
|
|
53
|
+
require 'time'
|
|
54
|
+
parse(string)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
require 'platypus/overload'
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
class TC_Overload_01 < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
class X
|
|
7
|
+
include Overloadable
|
|
8
|
+
|
|
9
|
+
def x
|
|
10
|
+
"hello"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
overload Array
|
|
14
|
+
|
|
15
|
+
def x(x)
|
|
16
|
+
[Array, x]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
overload Symbol
|
|
20
|
+
|
|
21
|
+
def x(x)
|
|
22
|
+
[Symbol, x]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def setup
|
|
27
|
+
@x = X.new
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_x
|
|
31
|
+
assert_equal( "hello", @x.x )
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_a
|
|
35
|
+
assert_equal( [Array, [1]], @x.x([1]) )
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_s
|
|
39
|
+
assert_equal( [Symbol, :a], @x.x(:a) )
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
class TC_Overload_02 < Test::Unit::TestCase
|
|
46
|
+
|
|
47
|
+
class X
|
|
48
|
+
include Overloadable
|
|
49
|
+
|
|
50
|
+
def x
|
|
51
|
+
"hello"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
overload Integer
|
|
55
|
+
|
|
56
|
+
def x(i)
|
|
57
|
+
i
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
overload String, String
|
|
61
|
+
|
|
62
|
+
def x(s1, s2)
|
|
63
|
+
[s1, s2]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def setup
|
|
69
|
+
@x = X.new
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_x
|
|
73
|
+
assert_equal( "hello", @x.x )
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def test_i
|
|
77
|
+
assert_equal( 1, @x.x(1) )
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_s
|
|
81
|
+
assert_equal( ["a","b"], @x.x("a","b") )
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
#
|
|
87
|
+
class TC_Overload_03 < Test::Unit::TestCase
|
|
88
|
+
|
|
89
|
+
class SubArray < Array
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
class SubSubArray < SubArray
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class X
|
|
96
|
+
include Overloadable
|
|
97
|
+
|
|
98
|
+
def x
|
|
99
|
+
"hello"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
overload Integer
|
|
103
|
+
|
|
104
|
+
def x(i)
|
|
105
|
+
i
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
overload Symbol
|
|
109
|
+
|
|
110
|
+
def x(s)
|
|
111
|
+
s
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
overload String, String
|
|
115
|
+
|
|
116
|
+
def x(s1, s2)
|
|
117
|
+
[s1, s2]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
overload Symbol, String
|
|
121
|
+
|
|
122
|
+
def x(s1, s2)
|
|
123
|
+
[s1, s2]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
overload Array
|
|
127
|
+
|
|
128
|
+
def x(a)
|
|
129
|
+
"array"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def setup
|
|
135
|
+
@x = X.new
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def test_x
|
|
139
|
+
assert_equal( "hello", @x.x )
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def test_i
|
|
143
|
+
assert_equal( 1, @x.x(1) )
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_strings
|
|
147
|
+
assert_equal( ["a","b"], @x.x("a","b") )
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def test_symbol_string
|
|
151
|
+
assert_equal( [:a,"b"], @x.x(:a,"b") )
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_sym
|
|
155
|
+
assert_equal( :sym, @x.x(:sym) )
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def test_subarray
|
|
159
|
+
assert_equal("array", @x.x([]))
|
|
160
|
+
assert_equal("array", @x.x(SubArray.new))
|
|
161
|
+
assert_equal("array", @x.x(SubSubArray.new))
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
#def test_raise
|
|
165
|
+
# assert_raise ArgumentError do
|
|
166
|
+
# X.module_eval do
|
|
167
|
+
# overload 42
|
|
168
|
+
# end
|
|
169
|
+
# end
|
|
170
|
+
#end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
|
metadata
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: platypus
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease: false
|
|
5
|
+
segments:
|
|
6
|
+
- 1
|
|
7
|
+
- 0
|
|
8
|
+
- 0
|
|
9
|
+
version: 1.0.0
|
|
10
|
+
platform: ruby
|
|
11
|
+
authors:
|
|
12
|
+
- Thomas Sawyer
|
|
13
|
+
- Jonas Pfenniger
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2010-05-27 00:00:00 -04:00
|
|
19
|
+
default_executable:
|
|
20
|
+
dependencies: []
|
|
21
|
+
|
|
22
|
+
description: Provides a complete double-dispatch type conversion system, method overloadability and psuedo-classes.
|
|
23
|
+
email:
|
|
24
|
+
executables: []
|
|
25
|
+
|
|
26
|
+
extensions: []
|
|
27
|
+
|
|
28
|
+
extra_rdoc_files:
|
|
29
|
+
- README
|
|
30
|
+
files:
|
|
31
|
+
- lib/platypus/core_ext.rb
|
|
32
|
+
- lib/platypus/overload.rb
|
|
33
|
+
- lib/platypus/type.rb
|
|
34
|
+
- lib/platypus/typecast.rb
|
|
35
|
+
- lib/platypus.rb
|
|
36
|
+
- test/test_overload.rb
|
|
37
|
+
- PROFILE
|
|
38
|
+
- LICENSE
|
|
39
|
+
- README
|
|
40
|
+
- HISTORY
|
|
41
|
+
- NOTES.rdoc
|
|
42
|
+
- REQUIRE
|
|
43
|
+
- VERSION
|
|
44
|
+
has_rdoc: true
|
|
45
|
+
homepage: http://rubyworks.github.com/platypus
|
|
46
|
+
licenses: []
|
|
47
|
+
|
|
48
|
+
post_install_message:
|
|
49
|
+
rdoc_options:
|
|
50
|
+
- --title
|
|
51
|
+
- Platypus API
|
|
52
|
+
- --main
|
|
53
|
+
- README
|
|
54
|
+
require_paths:
|
|
55
|
+
- lib
|
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
segments:
|
|
61
|
+
- 0
|
|
62
|
+
version: "0"
|
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
segments:
|
|
68
|
+
- 0
|
|
69
|
+
version: "0"
|
|
70
|
+
requirements: []
|
|
71
|
+
|
|
72
|
+
rubyforge_project: platypus
|
|
73
|
+
rubygems_version: 1.3.6
|
|
74
|
+
signing_key:
|
|
75
|
+
specification_version: 3
|
|
76
|
+
summary: Type Casting System
|
|
77
|
+
test_files:
|
|
78
|
+
- test/test_overload.rb
|