strongtyping 2.0.6 → 2.0.7

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/MANIFEST CHANGED
@@ -1,9 +1,11 @@
1
- ./t/functest.rb
2
- ./t/timetest.rb
3
- ./Makefile
4
- ./README.en
5
- ./extconf.rb
6
- ./strongtyping.c
7
- ./LGPL
8
- ./MANIFEST
9
- ./strongtyping.h
1
+ CHANGES
2
+ LGPL
3
+ MANIFEST
4
+ README
5
+ Rakefile
6
+ strongtyping.gemspec
7
+ ext/extconf.rb
8
+ ext/strongtyping.c
9
+ ext/strongtyping.h
10
+ test/functest.rb
11
+ test/timetest.rb
data/README ADDED
@@ -0,0 +1,330 @@
1
+ = Description
2
+ The strongtyping library is a provides a convenient way for Ruby methods
3
+ to check parameter types, and also dynamically query them. In addition to
4
+ merely checking a single set of types, it allows easy overloading based on
5
+ a number of different templates.
6
+
7
+ = Installation
8
+ gem install strongtyping
9
+
10
+ = Synopsis
11
+ Let's say you have the following function:
12
+
13
+ def foo(a, b)
14
+ ...
15
+ end
16
+
17
+ Now let's say this function wants 'a' to always be a String, and 'b'
18
+ should be Numeric:
19
+
20
+ require 'strongtyping'
21
+ include strongtyping
22
+
23
+ def foo(a, b)
24
+ expect(a, String, b, Numeric)
25
+ ...
26
+ end
27
+
28
+ If 'a' or 'b' is of the wrong type, an ArgumentTypeError will be raised.
29
+
30
+ Overloading is just as easy:
31
+
32
+ require 'strongtyping'
33
+ include strongtyping
34
+
35
+ def bar(*args)
36
+ overload(args, String, String){ |s1,s2|
37
+ ...
38
+ return
39
+ }
40
+
41
+ overload(args, String, Integer){ |s,i|
42
+ ...
43
+ return
44
+ }
45
+
46
+ overload_default args
47
+ end
48
+
49
+ If someone calls 'bar' with two Strings, or a String and an Integer,
50
+ the appropriate block will be called. Otherwise, an OverloadError
51
+ is raised.
52
+
53
+ How about default parameters? Say we have the following function:
54
+
55
+ def baz(a, b = nil)
56
+ action = "You baz #{a}";
57
+ action += " with a #{b}" if b
58
+
59
+ print action, "\n"
60
+ end
61
+
62
+ Now, b can either be nil or a String. We don't want to have two
63
+ full overload cases... that would duplicate code. So, expect()
64
+ allows an array of types:
65
+
66
+ expect(a, String, b, [String, NilClass]);
67
+
68
+ This takes care of the above case nicely.
69
+
70
+ What if your code is curious about which types are allowed? The
71
+ get_arg_types function is provided for just this purpose. Given the
72
+ above definitions for 'foo' and 'bar', consider the following code:
73
+
74
+ p get_arg_types(method(:foo)) # => [[String, Numeric]]
75
+ p get_arg_types(method(:bar)) # => [[String, String], [String, Integer]]
76
+ p get_arg_types(method(:baz)) # => [[String, [String, NilClass]]]
77
+
78
+ This is useful if you're converting user input into a form that the
79
+ method expects. (If you get "1234", should you convert it to an
80
+ integer, or is it best left a string? Now you know.)
81
+
82
+ What if you have an array of arguments, 'arr', and you're worried
83
+ that the method 'bar' won't accept them? You can check ahead of
84
+ time:
85
+
86
+ if not verify_args_for(method(:bar), arr)
87
+ print "I can't let you do that, Dave\n"
88
+ end
89
+
90
+ = Reference
91
+ Module: strongtyping
92
+
93
+ Methods:
94
+
95
+ expect(obj0, Module0[, obj1, Module1[,...objN, ModuleN]])
96
+
97
+ Verify the parameters obj0..objN are of the given class (or
98
+ module) Module0..ModuleN
99
+
100
+ overload(args, [Module0[, Module1[,...ModuleN]]]) { | o0, o1,..oN | }
101
+
102
+ Call the block with 'args' if they match the pattern
103
+ Module0..ModuleN. The block should _always_ call return at the
104
+ end.
105
+
106
+ overload_exception(args, [Module0[,...ModuleN]]]) { | o0, o1,..oN | }
107
+
108
+ This acts identically to overload(), except the case specified
109
+ is considered invalid, and thus not returned by get_arg_types().
110
+ It is expected that the specified block will throw an exception.
111
+
112
+ overload_default(args)
113
+ overload_error(args)
114
+
115
+ Raise OverloadError. This should _always_ be called after the
116
+ last overload() block. In addition to raising the exception,
117
+ it aids in checking parameters. As of 2.0, the overload_error
118
+ name is deprecated; use overload_default.
119
+
120
+ get_arg_types(Method)
121
+
122
+ Return an array of parameter templates. This is an array of
123
+ arrays, and will have multiple indices for functions using
124
+ multiple overload() blocks.
125
+
126
+ verify_args_for(method, args)
127
+
128
+ Verify the method 'method' will accept the arguments in array
129
+ 'args', returning a boolean result.
130
+
131
+ Exceptions:
132
+
133
+ ArgumentTypeError < ArgumentError
134
+
135
+ This exception is raised by expect() if the arguments do not
136
+ match the expected types.
137
+
138
+ OverloadError < ArgumentTypeError
139
+
140
+ This exception is raised by overload_default() if no overload()
141
+ template matches the given arguments.
142
+
143
+ = Q & A
144
+ This section written by Ryan Pavlik.
145
+
146
+ Q: Why?
147
+ A: Because it was originally needed for the Mephle library.
148
+
149
+ Q: No really, why bother with static typing? Isn't ruby dynamic?
150
+ A: This is not 'static typing'. This is 'strong typing'. Static
151
+ typing is what you get when a variable can only be of a certain
152
+ type, as in C or C++. Strong typing is enforcing types. These may
153
+ seem similar, but they are actually not directly related.
154
+
155
+ Some other languages, such as Common Lisp, allow for dynamic,
156
+ strong typing. Strong typing and dynamic typing are not mutually
157
+ exclusive.
158
+
159
+ Q: Yeah, but really, why bother? Why not just let ruby sort out the
160
+ errors as they occur?
161
+ A: This is incorrect thinking. Allowing errors to just occur when
162
+ they happen is naive programming. Consider the following:
163
+
164
+ # Wait N seconds, then open the bridge for M seconds
165
+ def sendMsg(bridge, n, m)
166
+ sleep(n)
167
+ bridge.open
168
+ sleep(m)
169
+ bridge.close
170
+ end
171
+
172
+ Now say 'm' is pased in as a string. Oops! A TypeError is
173
+ raised. Now the bridge is open, and somewhere (hopefully!) someone
174
+ caught the exception so the program didn't crash, but the bridge
175
+ opening wasn't reversed, so it's going to stay open and back up
176
+ traffic until someone fixes the problem.
177
+
178
+ This is an academic example, but there are many cases when just
179
+ letting an error happen will lead to an inconsistent system state.
180
+ Ruby (and most systems) are not transactional, and inconsistent
181
+ states are unacceptable.
182
+
183
+ In addition, it is desireable to know _programmatically_ why
184
+ something failed, as specific action can be taken if desired.
185
+
186
+ "Wait," someone in the audience says, "you could just check to see
187
+ if 'm' and 'n' are of the correct type!"
188
+
189
+ Yes, yes you could.
190
+
191
+ That's what this module is for. ;-)
192
+
193
+ Q: Isn't it up to the caller to call my function correctly?
194
+ A: The caller cannot know and deal with errors that may occur in your
195
+ code. That's your job. Checking for errors ahead of time and
196
+ informing the caller about problems is also your job. This module
197
+ just makes it easy.
198
+
199
+ In addition, it's nice for the caller to be able to ask and check
200
+ what your method expects ahead of time to guard against error.
201
+ The strongtyping module also provides functionality for this.
202
+
203
+ Q: OK, but strong typing is baaad. What if I want to pass something
204
+ that acts like something else, or responds to a given symbol?
205
+ Doesn't ruby have "duck" typing?
206
+ A: First, what you're suggesting is evil. If you want that, go
207
+ write C++. :-)
208
+
209
+ Second, you should never depend on a function's implementation. If
210
+ the documentation says "pass me a hash" and you pass it anything
211
+ that responds to :[], your code may break when the next version
212
+ comes out.
213
+
214
+ Third, if you pass something that responds accurately to the
215
+ _interface_ (methods provided by class or module) specified, then
216
+ that should be _of_ that class or module. This may not be the case
217
+ with all ruby objects yet; for instance, anything responding to :[]
218
+ being something like a Mappable. You can make this the case in
219
+ your code, or urge developers to create a standard set of interface
220
+ mixins for just this purpose.
221
+
222
+ "Duck" typing just a term for this sort of "maybe" behavior, much
223
+ like what C++ STL templates use. However, the problem is that even
224
+ if an object responds to a method, there is no guarantee that the
225
+ method acts in an expected manner---and the interface may still
226
+ change without notice. "Duck" typing sounds much like 'duct
227
+ taping' depending on your accent, and I think duct-taping is a good
228
+ description of this is in practice. :-)
229
+
230
+ Another argument is that ruby allows one to change the behavior of
231
+ methods at any time:
232
+
233
+ a = String.new;
234
+ def a.split
235
+ print "hello world\n"
236
+ end
237
+
238
+ For this, I have two responses: first, if a method is deprecated
239
+ or changed dramatically, strongtyping can aid in letting the code
240
+ know:
241
+
242
+ a = String.new;
243
+ def a.split(*args)
244
+ overload(args) { print "hello world\n" }
245
+ overload_default args
246
+ end
247
+
248
+ This case will drop any normal calls through to overload_default,
249
+ raising an exception, which can be caught and analyzed. You can
250
+ even provide another case that calls the superclass.
251
+
252
+ Second, either you're changing the method in a subtle manner (it
253
+ does what it used to, with added effect), or an outrageous manner
254
+ (it acts nothing like it did before). In the former case, code
255
+ should work fine anyway. In the latter case, as in the above
256
+ example, you should ask yourself why you're changing it. The
257
+ function no longer splits, why is it called split? This is not
258
+ good design; the strongtyping module is here to aid in good design,
259
+ not prevent poor design.
260
+
261
+ A more realistic example would be the academic "Shape" class
262
+ example of inheritance, with "Ellipse" and "Circle". Ruby properly
263
+ allows one to make Circle a subclass of Ellipse, and redefine
264
+ "setSize" to the constrained definition of a circle. This change
265
+ is visible to code---an ArgumentError will be raised (2 arguments
266
+ for 1), or setSize can throw a ConstraintError. strongtyping
267
+ provides a useful function, overload_exception, for just this case:
268
+
269
+ class Circle < Ellipse
270
+ :
271
+ def setSize(*args)
272
+ overload(args, Integer) {
273
+ | r |
274
+ @radius = r
275
+ return
276
+ }
277
+
278
+ overload_exception(args, Integer, Integer) {
279
+ | a, b |
280
+ raise ConstraintError
281
+ }
282
+
283
+ overload_default args
284
+ end
285
+ :
286
+ end
287
+
288
+ Of course, there are a number of good choices for handling
289
+ this... you may still allow #setSize(a, b) if a == b. The
290
+ important part is that the change in behavior can now be determined
291
+ by code.
292
+
293
+ Q: But I always write perfect code. I know what my functions do, and
294
+ what they take, and what I'm passing them.
295
+ A: No one writes perfect code. Additionally, not all environments are
296
+ as controlled as yours may be. Especially in a networked
297
+ environment when someone may be invoking a method remotely, you
298
+ can't depend on calling code not to be malicious.
299
+
300
+ Q: OK, OK. But, uh... what is Mephle?
301
+ A: Mephle is a soon-to-be-released network-transparent persistant
302
+ object system written in ruby. It uses many of the Unity concepts
303
+ (http://unity-project.sf.net/). It will be on the RAA when
304
+ released.
305
+
306
+ = License
307
+ strongtyping - Method parameter checking for Ruby
308
+ Copyright (C) 2003-2011 Ryan Pavlik
309
+
310
+ This library is free software; you can redistribute it and/or
311
+ modify it under the terms of the GNU Lesser General Public
312
+ License as published by the Free Software Foundation; either
313
+ version 2.1 of the License, or (at your option) any later version.
314
+
315
+ This library is distributed in the hope that it will be useful,
316
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
317
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
318
+ Lesser General Public License for more details.
319
+
320
+ You should have received a copy of the GNU Lesser General Public
321
+ License along with this library; if not, write to the Free Software
322
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
323
+
324
+ = Future Plans
325
+ There's some odd C code that is causing a couple of warnings, but it
326
+ does not appear to be harmful. I want to clean this code up eventually.
327
+
328
+ = Authors
329
+ * Ryan Pavlik (original author)
330
+ * Daniel Berger (maintenance)
@@ -0,0 +1,48 @@
1
+ require 'rake'
2
+ require 'rake/clean'
3
+ require 'rake/testtask'
4
+ require 'rbconfig'
5
+ include Config
6
+
7
+ CLEAN.include(
8
+ '**/*.gem', # Gem files
9
+ '**/*.rbc', # Rubinius
10
+ '**/*.o', # C object file
11
+ '**/*.log', # Ruby extension build log
12
+ '**/Makefile', # C Makefile
13
+ '**/conftest.dSYM', # OS X build directory
14
+ "**/*.#{CONFIG['DLEXT']}" # C shared object
15
+ )
16
+
17
+ desc "Build the strongtyping source"
18
+ task :build => [:clean] do
19
+ make = File::ALT_SEPARATOR ? "nmake" : "make"
20
+ Dir.chdir('ext') do
21
+ ruby 'extconf.rb'
22
+ sh "#{make}"
23
+ end
24
+ end
25
+
26
+ namespace 'gem' do
27
+ desc 'Create the strongtyping gem'
28
+ task :create => [:clean] do
29
+ Dir["*.gem"].each{ |f| File.delete(f) } # Clean first
30
+ spec = eval(IO.read('strongtyping.gemspec'))
31
+ Gem::Builder.new(spec).build
32
+ end
33
+
34
+ desc 'Install the strongtyping gem'
35
+ task :install => [:create] do
36
+ file = Dir["*.gem"].first
37
+ sh "gem install #{file}"
38
+ end
39
+ end
40
+
41
+ Rake::TestTask.new do |t|
42
+ task :test => :build
43
+ t.libs << 'ext'
44
+ t.verbose = true
45
+ t.warning = true
46
+ end
47
+
48
+ task :default => :test
@@ -1,3 +1,3 @@
1
- require 'mkmf'
2
-
3
- create_makefile "strongtyping"
1
+ require 'mkmf'
2
+
3
+ create_makefile "strongtyping"
@@ -0,0 +1,283 @@
1
+ /*
2
+ StrongTyping - Method parameter checking for Ruby
3
+ Copyright (C) 2003 Ryan Pavlik
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License as published by the Free Software Foundation; either
8
+ version 2.1 of the License, or (at your option) any later version.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ */
19
+
20
+ #include "ruby.h"
21
+ #include "strongtyping.h"
22
+
23
+ /* Ruby 1.9.x */
24
+ #ifndef RSTRING_PTR
25
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
26
+ #endif
27
+ #ifndef RSTRING_LEN
28
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
29
+ #endif
30
+
31
+ #ifndef RARRAY_PTR
32
+ #define RARRAY_PTR(a) (RARRAY(a)->ptr)
33
+ #endif
34
+ #ifndef RARRAY_LEN
35
+ #define RARRAY_LEN(a) (RARRAY(a)->len)
36
+ #endif
37
+
38
+ static int check_args(int argc, VALUE *obj, VALUE *mod);
39
+
40
+ static VALUE strongtyping_expect(int argc, VALUE *argv, VALUE self UNUSED) {
41
+ int i = 0;
42
+ VALUE obj[MAXARGS], mod[MAXARGS];
43
+ VALUE typestr;
44
+
45
+ if(!argc)
46
+ return Qnil;
47
+
48
+ if(argc % 2)
49
+ rb_raise(rb_eSyntaxError, "expect() requires argument pairs");
50
+
51
+ #ifndef __GNUC__
52
+ if(argc*2 > MAXARGS*2)
53
+ rb_raise(rb_eSyntaxError, "too many arguments to expect()");
54
+ #endif
55
+
56
+ for(i = 0; i < argc; i += 2) {
57
+ obj[i/2] = argv[i];
58
+ mod[(i+1)/2] = argv[i+1];
59
+ }
60
+
61
+ if(rb_funcall(obj[0], id_isa, 1, cQueryParams)) {
62
+ rb_funcall(obj[0], rb_intern("<<"), 1, rb_ary_new4(argc/2, mod));
63
+ rb_raise(eArgList, ""); // TODO: Why an empty string? Causes a warning in 1.9.x.
64
+ }
65
+
66
+ i = check_args(argc / 2, obj, mod);
67
+
68
+ if(i < 0)
69
+ return Qnil;
70
+
71
+ typestr = rb_funcall(mod[i], id_inspect, 0);
72
+
73
+ rb_raise(
74
+ eArgumentTypeError,
75
+ "Expecting %s as argument %d, got %s",
76
+ RSTRING_PTR(typestr), i + 1,
77
+ rb_class2name(rb_funcall(obj[i], id_class, 0))
78
+ );
79
+ }
80
+
81
+ static VALUE strongtyping_overload(int argc, VALUE *argv, VALUE self UNUSED) {
82
+ struct RArray *q;
83
+
84
+ if(argc < 1)
85
+ rb_raise(rb_eArgError, "At least one parameter required");
86
+
87
+ Check_Type(argv[0], T_ARRAY);
88
+ q = RARRAY(argv[0]);
89
+
90
+ if(RARRAY_LEN(q) && rb_funcall(RARRAY_PTR(q)[0], id_isa, 1, cQueryParams)) {
91
+ rb_funcall(RARRAY_PTR(q)[0], rb_intern("<<"), 1, rb_ary_new4(argc - 1, argv + 1));
92
+ return Qnil;
93
+ }
94
+
95
+ if(RARRAY_LEN(q) != (argc - 1))
96
+ return Qnil;
97
+
98
+ if(check_args(argc - 1, RARRAY_PTR(q), argv + 1) < 0){
99
+ if(argc == 2)
100
+ rb_yield(*RARRAY_PTR(*argv));
101
+ else
102
+ rb_yield(*argv);
103
+ }
104
+
105
+ return Qnil;
106
+ }
107
+
108
+ static VALUE strongtyping_overload_exception(int argc, VALUE *argv, VALUE self UNUSED) {
109
+ struct RArray *q;
110
+
111
+ if(argc < 1)
112
+ rb_raise(rb_eArgError, "At least one parameters required");
113
+
114
+ Check_Type(argv[0], T_ARRAY);
115
+ q = RARRAY(argv[0]);
116
+
117
+ if(RARRAY_LEN(q) && (argc - 1) == 0)
118
+ return Qnil;
119
+
120
+ if(check_args(argc - 1, RARRAY_PTR(q), argv + 1) < 0)
121
+ rb_yield(argv[0]);
122
+
123
+ return Qnil;
124
+ }
125
+
126
+ static VALUE strongtyping_overload_error(VALUE self UNUSED, VALUE args) {
127
+ struct RArray *q;
128
+ VALUE classlist;
129
+ const char *name = 0;
130
+ int i = 0;
131
+
132
+ Check_Type(args, T_ARRAY);
133
+ q = RARRAY(args);
134
+
135
+ if(RARRAY_LEN(q) && rb_funcall(RARRAY_PTR(q)[0], id_isa, 1, cQueryParams))
136
+ rb_raise(eArgList, "");
137
+
138
+ classlist = rb_str_new2("");
139
+
140
+ for(i = 0; i < RARRAY_LEN(q); i++) {
141
+ if(i > 0)
142
+ rb_str_cat(classlist, ", ", 2);
143
+
144
+ name = rb_class2name(rb_funcall(RARRAY_PTR(q)[i], id_class, 0));
145
+ rb_str_cat(classlist, name, strlen(name));
146
+ }
147
+
148
+ rb_raise(
149
+ eOverloadError,
150
+ "No matching template for arguments: [%s]",
151
+ RSTRING_PTR(classlist)
152
+ );
153
+ }
154
+
155
+ static int check_args(int argc, VALUE *obj, VALUE *mod) {
156
+ int i = 0;
157
+ VALUE ret;
158
+
159
+ for(i = 0; i < argc; i++){
160
+ if(TYPE(mod[i]) == T_ARRAY){
161
+ int j = 0, ok = 0;
162
+
163
+ for(j = 0; j < RARRAY_LEN(mod[i]); j++){
164
+ if(rb_funcall(obj[i], id_isa, 1, RARRAY_PTR(mod[i])[j]) == Qtrue)
165
+ ok = 1;
166
+ }
167
+
168
+ if(ok)
169
+ continue;
170
+ else
171
+ return i;
172
+ }
173
+ else{
174
+ ret = rb_funcall(obj[i], id_isa, 1, mod[i]);
175
+ if(ret == Qfalse) return i;
176
+ }
177
+ }
178
+
179
+ return -1;
180
+ }
181
+
182
+ static VALUE call_method(VALUE ary) {
183
+ VALUE method = RARRAY_PTR(ary)[0],
184
+ query = RARRAY_PTR(ary)[1];
185
+ VALUE *argv = NULL;
186
+ VALUE ret;
187
+ int argc = 0,
188
+ i = 0;
189
+
190
+ argc = FIX2INT(rb_funcall(method, rb_intern("arity"), 0));
191
+
192
+ if(argc == 0) {
193
+ rb_funcall(query, rb_intern("<<"), 1, rb_ary_new());
194
+ rb_raise(eArgList, "");
195
+ }
196
+ else if(argc < 0)
197
+ argc = -argc;
198
+
199
+ argv = malloc(sizeof(VALUE) * argc);
200
+ argv[0] = query;
201
+
202
+ for(i = 1; i < argc - 1; i++)
203
+ argv[i] = Qnil;
204
+
205
+ ret = rb_funcall2(method, rb_intern("call"), argc, argv);
206
+ free(argv);
207
+
208
+ return ret;
209
+ }
210
+
211
+ static VALUE grab_types(VALUE query) {
212
+ return query;
213
+ }
214
+
215
+ static VALUE strongtyping_get_arg_types(VALUE obj UNUSED, VALUE method) {
216
+ VALUE query, ary;
217
+ query = rb_funcall(cQueryParams, rb_intern("new"), 0);
218
+ ary = rb_ary_new3(2, method, query);
219
+
220
+ return rb_rescue2(call_method, ary, grab_types, query, eArgList, 0);
221
+ }
222
+
223
+ static VALUE strongtyping_verify_args_for(VALUE self, VALUE method, VALUE args) {
224
+ struct RArray *list = NULL;
225
+ struct RArray *t = NULL;
226
+ struct RArray *a = NULL;
227
+ int i = 0;
228
+ VALUE template = strongtyping_get_arg_types(self, method);
229
+
230
+ list = RARRAY(template);
231
+ a = RARRAY(args);
232
+
233
+ for(i = 0; i < RARRAY_LEN(list); i++){
234
+ t = RARRAY_PTR(list)[i];
235
+
236
+ if(RARRAY_LEN(a) != RARRAY_LEN(t))
237
+ continue;
238
+
239
+ if(check_args(RARRAY_LEN(a), RARRAY_PTR(a), RARRAY_PTR(t)) < 0)
240
+ return Qtrue;
241
+ }
242
+
243
+ return Qfalse;
244
+ }
245
+
246
+ void Init_strongtyping() {
247
+ mStrongTyping = rb_define_module("StrongTyping");
248
+ id_isa = rb_intern("is_a?");
249
+ id_class = rb_intern("class");
250
+ id_inspect = rb_intern("inspect");
251
+
252
+ /* 2.0.7: The version of the strongtyping library */
253
+ rb_define_const(mStrongTyping, "VERSION", rb_str_new2("2.0.7"));
254
+
255
+ cQueryParams = rb_define_class_under(mStrongTyping,
256
+ "%QueryParams",
257
+ rb_cArray);
258
+
259
+ eArgumentTypeError = rb_define_class_under(mStrongTyping,
260
+ "ArgumentTypeError",
261
+ rb_eArgError);
262
+ eOverloadError = rb_define_class_under(mStrongTyping,
263
+ "OverloadError",
264
+ eArgumentTypeError);
265
+ eArgList = rb_define_class_under(mStrongTyping,
266
+ "%ArgList",
267
+ rb_eException);
268
+
269
+ rb_define_module_function(mStrongTyping, "expect",
270
+ strongtyping_expect, -1);
271
+ rb_define_module_function(mStrongTyping, "overload",
272
+ strongtyping_overload, -1);
273
+ rb_define_module_function(mStrongTyping, "overload_exception",
274
+ strongtyping_overload_exception, -1);
275
+ rb_define_module_function(mStrongTyping, "overload_default",
276
+ strongtyping_overload_error, 1);
277
+ rb_define_module_function(mStrongTyping, "overload_error",
278
+ strongtyping_overload_error, 1);
279
+ rb_define_module_function(mStrongTyping, "get_arg_types",
280
+ strongtyping_get_arg_types, 1);
281
+ rb_define_module_function(mStrongTyping, "verify_args_for",
282
+ strongtyping_verify_args_for, 2);
283
+ }