strongtyping 2.0.6-x86-mswin32-60

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.
@@ -0,0 +1,9 @@
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
@@ -0,0 +1,420 @@
1
+ StrongTyping 2.0
2
+ ================
3
+
4
+ StrongTyping is a little ruby module that provides a convenient way
5
+ for ruby methods to check parameter types, and also dynamically
6
+ query them. In addition to merely checking a single set of types,
7
+ it allows easy overloading based on a number of different templates.
8
+
9
+ Changes
10
+ -------
11
+
12
+ 2.0.6b - Bugfix: Shouldn't get "too many arguments" on gcc
13
+ anymore.
14
+
15
+ 2.0.6a - Bugfix: Portability issues (zero-sized arrays and UNUSED
16
+ for non-GNU platforms fixed).
17
+
18
+ 2.0.6 - Bugfix: Types given after lists of types were not being
19
+ checked, as in the following:
20
+
21
+ expect(a, String, b, [Integer, String], d, String)
22
+
23
+ Before, 'd' could be any type and pass; now this is fixed.
24
+
25
+ 2.0.5 - Bugfix: overload "No matching template" was broken, and
26
+ I didn't notice.
27
+
28
+ Bugfix: get_arg_types fixed for no arguments; now returns []
29
+ in the right places for both overload() and expect().
30
+
31
+ Mod: Should compile without warnings with -W -Wall, at least
32
+ on gcc.
33
+
34
+ Mod: Added unit tests.
35
+
36
+ 2.0.4 - Bugfix: Optional arguments are now handled correctly
37
+ when doing get_arg_types.
38
+
39
+ 2.0.3 - It's a bit of a hack, but overload_default's "No matching
40
+ template" error now displays the given types, which makes
41
+ debugging a lot easier.
42
+
43
+ 2.0.2 - Change Object#type to Object#class for conformance with
44
+ Ruby 1.8
45
+
46
+ Bugfix: overload() range check that caused a segfault on
47
+ some systems
48
+
49
+ Bugfix: verify_args_for() should work now
50
+
51
+ 2.0.1 - Bugfix: overload() blocks with one parameter now receive the
52
+ parameter instead of an array
53
+
54
+ 2.0 - Rewritten in C for speed.
55
+ * As in 1.0.1, expect (and overload, etc) take arrays of
56
+ classes/modules
57
+
58
+ * overload_error is deprecated (but still available) in
59
+ favor of overload_default
60
+
61
+ * overload_exception acts as overload, but acts as an
62
+ "invalid" case; useful for invalid cases where a
63
+ specific exception should be thrown
64
+
65
+ * More on "duck typing" in the FAQ
66
+
67
+ 1.0.1 - [Not officially released] Added support for arrays of types
68
+ to expect(), as in expect(a, [Integer, NilClass])
69
+ 1.0 - First release
70
+
71
+ Requirements
72
+ ------------
73
+
74
+ * ruby 1.6
75
+ * C compiler
76
+
77
+ Install
78
+ -------
79
+
80
+ De-Compress archive and enter its top directory.
81
+ Then type:
82
+
83
+ $ ruby extconf.rb
84
+ $ make
85
+ ($ su)
86
+ # make install
87
+
88
+ Usage
89
+ -----
90
+
91
+ Let's say you have the following function:
92
+
93
+ def foo(a, b)
94
+ ...
95
+ end
96
+
97
+ Now let's say this function wants 'a' to always be a String, and 'b'
98
+ should be Numeric:
99
+
100
+ require 'strongtyping'
101
+ include StrongTyping
102
+
103
+ def foo(a, b)
104
+ expect(a, String, b, Numeric)
105
+ ...
106
+ end
107
+
108
+ If 'a' or 'b' is of the wrong type, an ArgumentTypeError will be
109
+ raised.
110
+
111
+ Overloading is just as easy:
112
+
113
+ require 'strongtyping'
114
+ include StrongTyping
115
+
116
+ def bar(*args)
117
+ overload(args, String, String) {
118
+ | s1, s2 |
119
+ ...
120
+ return
121
+ }
122
+
123
+ overload(args, String, Integer) {
124
+ | s, i |
125
+ ...
126
+ return
127
+ }
128
+
129
+ overload_default args
130
+ end
131
+
132
+ If someone calls 'bar' with two Strings, or a String and an Integer,
133
+ the appropriate block will be called. Otherwise, an OverloadError
134
+ is raised.
135
+
136
+ How about default parameters? Say we have the following function:
137
+
138
+ def baz(a, b = nil)
139
+ action = "You baz #{a}";
140
+ action += " with a #{b}" if b
141
+
142
+ print action, "\n"
143
+ end
144
+
145
+ Now, b can either be nil or a String. We don't want to have two
146
+ full overload cases... that would duplicate code. So, expect()
147
+ allows an array of types:
148
+
149
+ expect(a, String, b, [String, NilClass]);
150
+
151
+ This takes care of the above case nicely.
152
+
153
+ What if your code is curious about which types are allowed? The
154
+ get_arg_types function is provided for just this purpose. Given the
155
+ above definitions for 'foo' and 'bar', consider the following code:
156
+
157
+ p get_arg_types(method(:foo)) # => [[String, Numeric]]
158
+ p get_arg_types(method(:bar)) # => [[String, String], [String, Integer]]
159
+ p get_arg_types(method(:baz)) # => [[String, [String, NilClass]]]
160
+
161
+ This is useful if you're converting user input into a form that the
162
+ method expects. (If you get "1234", should you convert it to an
163
+ integer, or is it best left a string? Now you know.)
164
+
165
+ What if you have an array of arguments, 'arr', and you're worried
166
+ that the method 'bar' won't accept them? You can check ahead of
167
+ time:
168
+
169
+ if not verify_args_for(method(:bar), arr)
170
+ print "I can't let you do that, Dave\n"
171
+ end
172
+
173
+ Reference
174
+ ---------
175
+ Module: StrongTyping
176
+
177
+ Methods:
178
+
179
+ expect(obj0, Module0[, obj1, Module1[,...objN, ModuleN]])
180
+
181
+ Verify the parameters obj0..objN are of the given class (or
182
+ module) Module0..ModuleN
183
+
184
+ overload(args, [Module0[, Module1[,...ModuleN]]]) { | o0, o1,..oN | }
185
+
186
+ Call the block with 'args' if they match the pattern
187
+ Module0..ModuleN. The block should _always_ call return at the
188
+ end.
189
+
190
+ overload_exception(args, [Module0[,...ModuleN]]]) { | o0, o1,..oN | }
191
+
192
+ This acts identically to overload(), except the case specified
193
+ is considered invalid, and thus not returned by get_arg_types().
194
+ It is expected that the specified block will throw an exception.
195
+
196
+ overload_default(args)
197
+ overload_error(args)
198
+
199
+ Raise OverloadError. This should _always_ be called after the
200
+ last overload() block. In addition to raising the exception,
201
+ it aids in checking parameters. As of 2.0, the overload_error
202
+ name is deprecated; use overload_default.
203
+
204
+ get_arg_types(Method)
205
+
206
+ Return an array of parameter templates. This is an array of
207
+ arrays, and will have multiple indices for functions using
208
+ multiple overload() blocks.
209
+
210
+ verify_args_for(method, args)
211
+
212
+ Verify the method 'method' will accept the arguments in array
213
+ 'args', returning a boolean result.
214
+
215
+ Exceptions:
216
+
217
+ ArgumentTypeError < ArgumentError
218
+
219
+ This exception is raised by expect() if the arguments do not
220
+ match the expected types.
221
+
222
+ OverloadError < ArgumentTypeError
223
+
224
+ This exception is raised by overload_default() if no overload()
225
+ template matches the given arguments.
226
+
227
+ FAQ
228
+ ---
229
+ These aren't actually FAQs (yet), but some issues that _have_ been
230
+ brought up.
231
+
232
+ Q: Why?
233
+ A: Because I need it for Mephle. :-)
234
+
235
+
236
+ Q: No really, why bother with static typing? Isn't ruby dynamic?
237
+ A: This is not 'static typing'. This is 'strong typing'. Static
238
+ typing is what you get when a variable can only be of a certain
239
+ type, as in C or C++. Strong typing is enforcing types. These may
240
+ seem similar, but they are actually not directly related.
241
+
242
+ Some other languages, such as Common Lisp, allow for dynamic,
243
+ strong typing. Strong typing and dynamic typing are not mutually
244
+ exclusive.
245
+
246
+
247
+ Q: Yeah, but really, why bother? Why not just let ruby sort out the
248
+ errors as they occur?
249
+ A: This is incorrect thinking. Allowing errors to just occur when
250
+ they happen is naive programming. Consider the following:
251
+
252
+ # Wait N seconds, then open the bridge for M seconds
253
+ def sendMsg(bridge, n, m)
254
+ sleep(n)
255
+ bridge.open
256
+ sleep(m)
257
+ bridge.close
258
+ end
259
+
260
+ Now say 'm' is pased in as a string. Oops! A TypeError is
261
+ raised. Now the bridge is open, and somewhere (hopefully!) someone
262
+ caught the exception so the program didn't crash, but the bridge
263
+ opening wasn't reversed, so it's going to stay open and back up
264
+ traffic until someone fixes the problem.
265
+
266
+ This is an academic example, but there are many cases when just
267
+ letting an error happen will lead to an inconsistent system state.
268
+ Ruby (and most systems) are not transactional, and inconsistent
269
+ states are unacceptable.
270
+
271
+ In addition, it is desireable to know _programmatically_ why
272
+ something failed, as specific action can be taken if desired.
273
+
274
+ "Wait," someone in the audience says, "you could just check to see
275
+ if 'm' and 'n' are of the correct type!"
276
+
277
+ Yes, yes you could.
278
+
279
+ That's what this module is for. ;-)
280
+
281
+
282
+ Q: Isn't it up to the caller to call my function correctly?
283
+ A: The caller cannot know and deal with errors that may occur in your
284
+ code. That's your job. Checking for errors ahead of time and
285
+ informing the caller about problems is also your job. This module
286
+ just makes it easy.
287
+
288
+ In addition, it's nice for the caller to be able to ask and check
289
+ what your method expects ahead of time to guard against error.
290
+ The StrongTyping module also provides functionality for this.
291
+
292
+
293
+ Q: OK, but strong typing is baaad. What if I want to pass something
294
+ that acts like something else, or responds to a given symbol?
295
+ Doesn't ruby have "duck" typing?
296
+ A: First, what you're suggesting is evil. If you want that, go
297
+ write C++. :-)
298
+
299
+ Second, you should never depend on a function's implementation. If
300
+ the documentation says "pass me a hash" and you pass it anything
301
+ that responds to :[], your code may break when the next version
302
+ comes out.
303
+
304
+ Third, if you pass something that responds accurately to the
305
+ _interface_ (methods provided by class or module) specified, then
306
+ that should be _of_ that class or module. This may not be the case
307
+ with all ruby objects yet; for instance, anything responding to :[]
308
+ being something like a Mappable. You can make this the case in
309
+ your code, or urge developers to create a standard set of interface
310
+ mixins for just this purpose.
311
+
312
+ "Duck" typing just a term for this sort of "maybe" behavior, much
313
+ like what C++ STL templates use. However, the problem is that even
314
+ if an object responds to a method, there is no guarantee that the
315
+ method acts in an expected manner---and the interface may still
316
+ change without notice. "Duck" typing sounds much like 'duct
317
+ taping' depending on your accent, and I think duct-taping is a good
318
+ description of this is in practice. :-)
319
+
320
+ Another argument is that ruby allows one to change the behavior of
321
+ methods at any time:
322
+
323
+ a = String.new;
324
+ def a.split
325
+ print "hello world\n"
326
+ end
327
+
328
+ For this, I have two responses: first, if a method is deprecated
329
+ or changed dramatically, StrongTyping can aid in letting the code
330
+ know:
331
+
332
+ a = String.new;
333
+ def a.split(*args)
334
+ overload(args) { print "hello world\n" }
335
+ overload_default args
336
+ end
337
+
338
+ This case will drop any normal calls through to overload_default,
339
+ raising an exception, which can be caught and analyzed. You can
340
+ even provide another case that calls the superclass.
341
+
342
+ Second, either you're changing the method in a subtle manner (it
343
+ does what it used to, with added effect), or an outrageous manner
344
+ (it acts nothing like it did before). In the former case, code
345
+ should work fine anyway. In the latter case, as in the above
346
+ example, you should ask yourself why you're changing it. The
347
+ function no longer splits, why is it called split? This is not
348
+ good design; the StrongTyping module is here to aid in good design,
349
+ not prevent poor design.
350
+
351
+ A more realistic example would be the academic "Shape" class
352
+ example of inheritance, with "Ellipse" and "Circle". Ruby properly
353
+ allows one to make Circle a subclass of Ellipse, and redefine
354
+ "setSize" to the constrained definition of a circle. This change
355
+ is visible to code---an ArgumentError will be raised (2 arguments
356
+ for 1), or setSize can throw a ConstraintError. StrongTyping
357
+ provides a useful function, overload_exception, for just this case:
358
+
359
+ class Circle < Ellipse
360
+ :
361
+ def setSize(*args)
362
+ overload(args, Integer) {
363
+ | r |
364
+ @radius = r
365
+ return
366
+ }
367
+
368
+ overload_exception(args, Integer, Integer) {
369
+ | a, b |
370
+ raise ConstraintError
371
+ }
372
+
373
+ overload_default args
374
+ end
375
+ :
376
+ end
377
+
378
+ Of course, there are a number of good choices for handling
379
+ this... you may still allow #setSize(a, b) if a == b. The
380
+ important part is that the change in behavior can now be determined
381
+ by code.
382
+
383
+
384
+ Q: But I always write perfect code. I know what my functions do, and
385
+ what they take, and what I'm passing them.
386
+ A: No one writes perfect code. Additionally, not all environments are
387
+ as controlled as yours may be. Especially in a networked
388
+ environment when someone may be invoking a method remotely, you
389
+ can't depend on calling code not to be malicious.
390
+
391
+
392
+ Q: OK, OK. But, uh... what is Mephle?
393
+ A: Mephle is a soon-to-be-released network-transparent persistant
394
+ object system written in ruby. It uses many of the Unity concepts
395
+ (http://unity-project.sf.net/). It will be on the RAA when
396
+ released.
397
+
398
+
399
+ License
400
+ -------
401
+
402
+ StrongTyping - Method parameter checking for Ruby
403
+ Copyright (C) 2003 Ryan Pavlik
404
+
405
+ This library is free software; you can redistribute it and/or
406
+ modify it under the terms of the GNU Lesser General Public
407
+ License as published by the Free Software Foundation; either
408
+ version 2.1 of the License, or (at your option) any later version.
409
+
410
+ This library is distributed in the hope that it will be useful,
411
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
412
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
413
+ Lesser General Public License for more details.
414
+
415
+ You should have received a copy of the GNU Lesser General Public
416
+ License along with this library; if not, write to the Free Software
417
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
418
+
419
+
420
+ Ryan Pavlik <rpav@mephle.com>
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile "strongtyping"
Binary file
@@ -0,0 +1,247 @@
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
+ static int check_args(int argc, VALUE *obj, VALUE *mod);
24
+
25
+ static VALUE
26
+ strongtyping_expect(int argc, VALUE *argv, VALUE self UNUSED) {
27
+ int i = 0;
28
+ VALUE obj[MAXARGS], mod[MAXARGS];
29
+ VALUE typestr;
30
+
31
+ if(!argc) return Qnil;
32
+ if(argc % 2)
33
+ rb_raise(rb_eSyntaxError, "expect() requires argument pairs");
34
+
35
+ #ifndef __GNUC__
36
+ if(argc*2 > MAXARGS*2)
37
+ rb_raise(rb_eSyntaxError, "too many arguments to expect()");
38
+ #endif
39
+
40
+ for(i = 0; i < argc; i += 2) {
41
+ obj[i/2] = argv[i];
42
+ mod[(i+1)/2] = argv[i+1];
43
+ }
44
+
45
+ if(rb_funcall(obj[0], id_isa, 1, cQueryParams)) {
46
+ rb_funcall(obj[0], rb_intern("<<"), 1, rb_ary_new4(argc/2, mod));
47
+ rb_raise(eArgList, "");
48
+ }
49
+
50
+ i = check_args(argc / 2, obj, mod);
51
+
52
+ if(i < 0) return Qnil;
53
+
54
+ typestr = rb_funcall(mod[i], id_inspect, 0);
55
+ rb_raise(eArgumentTypeError, "Expecting %s as argument %d, got %s",
56
+ RSTRING(typestr)->ptr, i + 1,
57
+ rb_class2name(rb_funcall(obj[i], id_class, 0)));
58
+ }
59
+
60
+ static VALUE
61
+ strongtyping_overload(int argc, VALUE *argv, VALUE self UNUSED) {
62
+ struct RArray *q;
63
+
64
+ if(argc < 1)
65
+ rb_raise(rb_eArgError, "At least one parameter required");
66
+
67
+ Check_Type(argv[0], T_ARRAY);
68
+ q = RARRAY(argv[0]);
69
+
70
+ if(q->len && rb_funcall(q->ptr[0], id_isa, 1, cQueryParams)) {
71
+ rb_funcall(q->ptr[0], rb_intern("<<"), 1,
72
+ rb_ary_new4(argc - 1, argv + 1));
73
+ return Qnil;
74
+ }
75
+
76
+ if(q->len != (argc - 1))
77
+ return Qnil;
78
+
79
+ if(check_args(argc - 1, q->ptr, argv + 1) < 0) {
80
+ if(argc == 2) rb_yield(*RARRAY(*argv)->ptr);
81
+ else rb_yield(*argv);
82
+ }
83
+
84
+ return Qnil;
85
+ }
86
+
87
+ static VALUE
88
+ strongtyping_overload_exception(int argc, VALUE *argv, VALUE self UNUSED) {
89
+ struct RArray *q;
90
+
91
+ if(argc < 1)
92
+ rb_raise(rb_eArgError, "At least one parameters required");
93
+
94
+ Check_Type(argv[0], T_ARRAY);
95
+ q = RARRAY(argv[0]);
96
+
97
+ if(q->len && (argc - 1) == 0)
98
+ return Qnil;
99
+
100
+ if(check_args(argc - 1, q->ptr, argv + 1) < 0)
101
+ rb_yield(argv[0]);
102
+
103
+ return Qnil;
104
+ }
105
+
106
+ static VALUE
107
+ strongtyping_overload_error(VALUE self UNUSED, VALUE args) {
108
+ struct RArray *q;
109
+ VALUE classlist;
110
+ char *name = 0;
111
+ int i = 0;
112
+
113
+ Check_Type(args, T_ARRAY);
114
+ q = RARRAY(args);
115
+
116
+ if(q->len && rb_funcall(q->ptr[0], id_isa, 1, cQueryParams))
117
+ rb_raise(eArgList, "");
118
+
119
+ classlist = rb_str_new2("");
120
+ for(i = 0; i < q->len; i++) {
121
+ if(i > 0) rb_str_cat(classlist, ", ", 2);
122
+ name = rb_class2name(rb_funcall(q->ptr[i], id_class, 0));
123
+ rb_str_cat(classlist, name, strlen(name));
124
+ }
125
+ rb_raise(eOverloadError, "No matching template for arguments: [%s]",
126
+ RSTRING(classlist)->ptr);
127
+ }
128
+
129
+ static int
130
+ check_args(int argc, VALUE *obj, VALUE *mod) {
131
+ int i = 0;
132
+ VALUE ret;
133
+
134
+ for(i = 0; i < argc; i++) {
135
+ if(TYPE(mod[i]) == T_ARRAY) {
136
+ int j = 0, ok = 0;
137
+ for(j = 0; j < RARRAY(mod[i])->len; j++)
138
+ if(rb_funcall(obj[i], id_isa, 1, RARRAY(mod[i])->ptr[j]) == Qtrue)
139
+ ok = 1;
140
+
141
+ if(ok) continue;
142
+ else return i;
143
+ } else {
144
+ ret = rb_funcall(obj[i], id_isa, 1, mod[i]);
145
+ if(ret == Qfalse) return i;
146
+ }
147
+ }
148
+
149
+ return -1;
150
+ }
151
+
152
+ static VALUE
153
+ call_method(VALUE ary) {
154
+ VALUE method = RARRAY(ary)->ptr[0],
155
+ query = RARRAY(ary)->ptr[1];
156
+ VALUE *argv = NULL;
157
+ VALUE ret;
158
+ int argc = 0,
159
+ i = 0;
160
+
161
+ argc = FIX2INT(rb_funcall(method, rb_intern("arity"), 0));
162
+ if(argc == 0) {
163
+ rb_funcall(query, rb_intern("<<"), 1, rb_ary_new());
164
+ rb_raise(eArgList, "");
165
+ } else if(argc < 0) argc = -argc;
166
+
167
+ argv = malloc(sizeof(VALUE) * argc);
168
+ argv[0] = query;
169
+ for(i = 1; i < argc - 1; i++) argv[i] = Qnil;
170
+
171
+ ret = rb_funcall2(method, rb_intern("call"), argc, argv);
172
+ free(argv);
173
+
174
+ return ret;
175
+ }
176
+
177
+ static VALUE
178
+ grab_types(VALUE query) {
179
+ return query;
180
+ }
181
+
182
+ static VALUE
183
+ strongtyping_get_arg_types(VALUE obj UNUSED, VALUE method) {
184
+ VALUE query, ary;
185
+ query = rb_funcall(cQueryParams, rb_intern("new"), 0);
186
+ ary = rb_ary_new3(2, method, query);
187
+
188
+ return rb_rescue2(call_method, ary, grab_types, query, eArgList, 0);
189
+ }
190
+
191
+
192
+ static VALUE
193
+ strongtyping_verify_args_for(VALUE self, VALUE method, VALUE args) {
194
+ struct RArray *list = NULL,
195
+ *t = NULL,
196
+ *a = NULL;
197
+ int i = 0;
198
+ VALUE template = strongtyping_get_arg_types(self, method);
199
+
200
+ list = RARRAY(template);
201
+ a = RARRAY(args);
202
+
203
+ for(i = 0; i < list->len; i++) {
204
+ t = RARRAY(list->ptr[i]);
205
+
206
+ if(a->len != t->len) continue;
207
+ if(check_args(a->len, a->ptr, t->ptr) < 0) return Qtrue;
208
+ }
209
+
210
+ return Qfalse;
211
+ }
212
+
213
+ void Init_strongtyping() {
214
+ mStrongTyping = rb_define_module("StrongTyping");
215
+ id_isa = rb_intern("is_a?");
216
+ id_class = rb_intern("class");
217
+ id_inspect = rb_intern("inspect");
218
+
219
+ cQueryParams = rb_define_class_under(mStrongTyping,
220
+ "%QueryParams",
221
+ rb_cArray);
222
+
223
+ eArgumentTypeError = rb_define_class_under(mStrongTyping,
224
+ "ArgumentTypeError",
225
+ rb_eArgError);
226
+ eOverloadError = rb_define_class_under(mStrongTyping,
227
+ "OverloadError",
228
+ eArgumentTypeError);
229
+ eArgList = rb_define_class_under(mStrongTyping,
230
+ "%ArgList",
231
+ rb_eException);
232
+
233
+ rb_define_module_function(mStrongTyping, "expect",
234
+ strongtyping_expect, -1);
235
+ rb_define_module_function(mStrongTyping, "overload",
236
+ strongtyping_overload, -1);
237
+ rb_define_module_function(mStrongTyping, "overload_exception",
238
+ strongtyping_overload_exception, -1);
239
+ rb_define_module_function(mStrongTyping, "overload_default",
240
+ strongtyping_overload_error, 1);
241
+ rb_define_module_function(mStrongTyping, "overload_error",
242
+ strongtyping_overload_error, 1);
243
+ rb_define_module_function(mStrongTyping, "get_arg_types",
244
+ strongtyping_get_arg_types, 1);
245
+ rb_define_module_function(mStrongTyping, "verify_args_for",
246
+ strongtyping_verify_args_for, 2);
247
+ }