ruby-fizzbuzz 0.7.0 → 0.8.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.
@@ -1,64 +1,48 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- # :enddoc:
4
-
5
- #
6
- # extconf.rb
7
- #
8
- # Copyright 2012-2014 Krzysztof Wilczynski
9
- #
10
- # Licensed under the Apache License, Version 2.0 (the "License");
11
- # you may not use this file except in compliance with the License.
12
- # You may obtain a copy of the License at
13
- #
14
- # http://www.apache.org/licenses/LICENSE-2.0
15
- #
16
- # Unless required by applicable law or agreed to in writing, software
17
- # distributed under the License is distributed on an "AS IS" BASIS,
18
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
- # See the License for the specific language governing permissions and
20
- # limitations under the License.
21
- #
1
+ # frozen_string_literal: true
22
2
 
23
3
  require 'mkmf'
24
4
 
25
5
  RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
26
6
 
27
- $CFLAGS << ' -std=c99 -g -Wall -Wextra -pedantic'
7
+ $CFLAGS << ' -std=c99 -Wall -Wextra -pedantic'
28
8
 
29
- unless RbConfig::CONFIG['host_os'][/darwin/]
9
+ if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/
10
+ $CFLAGS << ' -O3' unless $CFLAGS =~ /-O\d/
11
+ $CFLAGS << ' -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline'
12
+ end
13
+
14
+ unless RbConfig::CONFIG['host_os'] =~ /darwin/
30
15
  $LDFLAGS << ' -Wl,--as-needed'
31
16
  end
32
17
 
33
- $LDFLAGS << " %s" % ENV['LDFLAGS'] if ENV['LDFLAGS']
18
+ $LDFLAGS << format(' %s', ENV['LDFLAGS']) if ENV['LDFLAGS']
34
19
 
35
20
  %w(CFLAGS CXXFLAGS CPPFLAGS).each do |variable|
36
- $CFLAGS << " %s" % ENV[variable] if ENV[variable]
21
+ $CFLAGS << format(' %s', ENV[variable]) if ENV[variable]
37
22
  end
38
23
 
39
24
  unless have_header('ruby.h')
40
- abort <<-EOS
41
-
42
- You appear to be missing Ruby development libraries and/or header
43
- files. You can install missing compile-time dependencies in one of
44
- the following ways:
25
+ abort "\n" + (<<-EOS).gsub(/^[ ]{,3}/, '') + "\n"
26
+ You appear to be missing Ruby development libraries and/or header
27
+ files. You can install missing compile-time dependencies in one of
28
+ the following ways:
45
29
 
46
- - Debian / Ubuntu
30
+ - Debian / Ubuntu
47
31
 
48
- apt-get install ruby-dev
32
+ apt-get install ruby-dev
49
33
 
50
- - Red Hat / CentOS / Fedora
34
+ - Red Hat / CentOS / Fedora
51
35
 
52
- yum install ruby-devel
36
+ yum install ruby-devel or dnf install ruby-devel
53
37
 
54
38
 
55
- Alternatively, you can use either of the following Ruby version
56
- managers in order to install Ruby locally (for your user only)
57
- and/or system-wide:
58
-
59
- - Ruby Version Manager (for RVM, see http://rvm.io/)
60
- - Ruby Environment (for rbenv, see http://github.com/sstephenson/rbenv)
39
+ Alternatively, you can use either of the following Ruby version
40
+ managers in order to install Ruby locally (for your user only)
41
+ and/or system-wide:
61
42
 
43
+ - Ruby Version Manager (for RVM, see http://rvm.io/)
44
+ - Ruby Environment (for rbenv, see http://github.com/sstephenson/rbenv)
45
+ - Change Ruby (for chruby, see https://github.com/postmodern/chruby)
62
46
  EOS
63
47
  end
64
48
 
@@ -66,6 +50,3 @@ dir_config('fizzbuzz')
66
50
 
67
51
  create_header
68
52
  create_makefile('fizzbuzz/fizzbuzz')
69
-
70
- # vim: set ts=2 sw=2 sts=2 et :
71
- # encoding: utf-8
@@ -1,23 +1,3 @@
1
- /* :stopdoc: */
2
-
3
- /*
4
- * fizzbuzz.c
5
- *
6
- * Copyright 2012-2014 Krzysztof Wilczynski
7
- *
8
- * Licensed under the Apache License, Version 2.0 (the "License");
9
- * you may not use this file except in compliance with the License.
10
- * You may obtain a copy of the License at
11
- *
12
- * http://www.apache.org/licenses/LICENSE-2.0
13
- *
14
- * Unless required by applicable law or agreed to in writing, software
15
- * distributed under the License is distributed on an "AS IS" BASIS,
16
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- * See the License for the specific language governing permissions and
18
- * limitations under the License.
19
- */
20
-
21
1
  #if defined(__cplusplus)
22
2
  extern "C" {
23
3
  #endif
@@ -36,16 +16,14 @@ void Init_fizzbuzz(void);
36
16
 
37
17
  static VALUE fizzbuzz_evaluate(VALUE value);
38
18
  static VALUE fizzbuzz_values(VALUE object, fizzbuzz_return_t type,
39
- fizzbuzz_direction_t direction);
19
+ fizzbuzz_direction_t direction);
40
20
 
41
21
  static VALUE fizzbuzz_exception_wrapper(VALUE value);
42
22
  static VALUE fizzbuzz_exception(void *data);
43
23
 
44
24
  static VALUE fizzbuzz_type_error(VALUE klass, const char *message);
45
25
  static VALUE fizzbuzz_range_error(VALUE klass, VALUE start, VALUE stop,
46
- const char *message);
47
-
48
- /* :startdoc: */
26
+ const char *message);
49
27
 
50
28
  /*
51
29
  * call-seq:
@@ -59,16 +37,17 @@ static VALUE fizzbuzz_range_error(VALUE klass, VALUE start, VALUE stop,
59
37
  *
60
38
  * Example:
61
39
  *
62
- * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xb6fd3b38 @stop=100, @start=1>
63
- * fb = FizzBuzz.new(-100,-1) #=> #<FizzBuzz:0xb72d5700 @stop=-1, @start=-100>
64
- * fb = FizzBuzz.new(-15, 15) #=> #<FizzBuzz:0xb6fd0460 @stop=15, @start=-15>
40
+ * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xb6fd3b38 @stop=100, @start=1>
41
+ * fb = FizzBuzz.new(-100, -1) #=> #<FizzBuzz:0xb72d5700 @stop=-1, @start=-100>
42
+ * fb = FizzBuzz.new(-15, 15) #=> #<FizzBuzz:0xb6fd0460 @stop=15, @start=-15>
65
43
  *
66
44
  * The given value of +stop+ must always be greater than or equal to the
67
45
  * given value of +start+, otherwise raises an <i>FizzBuzz::RangeError</i>
68
46
  * exception.
69
47
  *
70
48
  * Will raise a <i>FizzBuzz::TypeError</i> exception if given value of either
71
- * +start+ or +stop+ is not an _Fixnum_ or _Bignum_ type.
49
+ * +start+ or +stop+ is not a _Fixnum_ or _Bignum_ type, or an _Integer_ type
50
+ * starting from Ruby version 2.4 onwards.
72
51
  *
73
52
  * See also: FizzBuzz::fizzbuzz and FizzBuzz::[]
74
53
  */
@@ -92,14 +71,14 @@ rb_fb_initialize(int argc, VALUE *argv, VALUE object)
92
71
 
93
72
  /*
94
73
  * call-seq:
95
- * fizzfuzz.start -> integer
74
+ * fizzbuzz.start -> integer
96
75
  *
97
76
  * Returns the current value for +start+.
98
77
  *
99
78
  * Example:
100
79
  *
101
- * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xf726b48c @stop=100, @start=1>
102
- * fb.start #=> 1
80
+ * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xf726b48c @stop=100, @start=1>
81
+ * fb.start #=> 1
103
82
  */
104
83
  VALUE
105
84
  rb_fb_get_start(VALUE object)
@@ -109,7 +88,7 @@ rb_fb_get_start(VALUE object)
109
88
 
110
89
  /*
111
90
  * call-seq:
112
- * fizzfuzz.start= (integer) -> integer
91
+ * fizzbuzz.start=( integer ) -> integer
113
92
  *
114
93
  * Sets the current value of +start+ if given new value is lower or equal
115
94
  * to the current value of +stop+, or raises an <i>FizzBuzz::RangeError</i>
@@ -117,13 +96,14 @@ rb_fb_get_start(VALUE object)
117
96
  *
118
97
  * Examples:
119
98
  *
120
- * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xf726f03c @stop=100, @start=1>
121
- * fb.start #=> 1
122
- * fb.start = 15 #=> 15
123
- * fb.start #=> 15
99
+ * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xf726f03c @stop=100, @start=1>
100
+ * fb.start #=> 1
101
+ * fb.start = 15 #=> 15
102
+ * fb.start #=> 15
124
103
  *
125
104
  * Will raise a <i>FizzBuzz::TypeError</i> exception if given value is not
126
- * an _Fixnum_ or _Bignum_ type.
105
+ * a _Fixnum_ or _Bignum_ type, or an _Integer_ type starting from Ruby
106
+ * version 2.4 onwards.
127
107
  */
128
108
  VALUE
129
109
  rb_fb_set_start(VALUE object, VALUE value)
@@ -138,14 +118,14 @@ rb_fb_set_start(VALUE object, VALUE value)
138
118
 
139
119
  /*
140
120
  * call-seq:
141
- * fizzfuzz.stop -> integer
121
+ * fizzbuzz.stop -> integer
142
122
  *
143
123
  * Returns the current value for +stop+.
144
124
  *
145
125
  * Example:
146
126
  *
147
- * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xf7272bec @stop=100, @start=1>
148
- * fb.stop #=> 100
127
+ * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xf7272bec @stop=100, @start=1>
128
+ * fb.stop #=> 100
149
129
  */
150
130
  VALUE
151
131
  rb_fb_get_stop(VALUE object)
@@ -155,7 +135,7 @@ rb_fb_get_stop(VALUE object)
155
135
 
156
136
  /*
157
137
  * call-seq:
158
- * fizzfuzz.stop= (integer) -> integer
138
+ * fizzbuzz.stop=( integer ) -> integer
159
139
  *
160
140
  * Sets the current value of +stop+ if given new value is greater or equal
161
141
  * to the current value of +start+, or raises an <i>FizzBuzz::RangeError</i>
@@ -163,13 +143,14 @@ rb_fb_get_stop(VALUE object)
163
143
  *
164
144
  * Example:
165
145
  *
166
- * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xf727679c @stop=100, @start=1>
167
- * fb.stop #=> 100
168
- * fb.stop = 15 #=> 15
169
- * fb.stop #=> 15
146
+ * fb = FizzBuzz.new(1, 100) #=> #<FizzBuzz:0xf727679c @stop=100, @start=1>
147
+ * fb.stop #=> 100
148
+ * fb.stop = 15 #=> 15
149
+ * fb.stop #=> 15
170
150
  *
171
151
  * Will raise a <i>FizzBuzz::TypeError</i> exception if given value is not
172
- * an _Fixnum_ or _Bignum_ type.
152
+ * a _Fixnum_ or _Bignum_ type, or an _Integer_ type starting from Ruby
153
+ * version 2.4 onwards.
173
154
  */
174
155
  VALUE
175
156
  rb_fb_set_stop(VALUE object, VALUE value)
@@ -191,8 +172,8 @@ rb_fb_set_stop(VALUE object, VALUE value)
191
172
  *
192
173
  * Example:
193
174
  *
194
- * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xf727fd60 @stop=15, @start=1>
195
- * fb.to_a #=> [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz"]
175
+ * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xf727fd60 @stop=15, @start=1>
176
+ * fb.to_a #=> [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz"]
196
177
  *
197
178
  * See also: FizzBuzz::fizzbuzz
198
179
  */
@@ -205,7 +186,7 @@ rb_fb_array(VALUE object)
205
186
  /*
206
187
  * call-seq:
207
188
  * fizzbuzz.each {|value| block } -> self
208
- * fizzbuzz.each -> an Enumerator
189
+ * fizzbuzz.each -> an Enumerator
209
190
  *
210
191
  * Calls the block _once_ for each subsequent value for a given range
211
192
  * from +start+ to +stop+, passing the value as a parameter to the block.
@@ -214,12 +195,12 @@ rb_fb_array(VALUE object)
214
195
  *
215
196
  * Example:
216
197
  *
217
- * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xf722f8ec @stop=15, @start=1>
218
- * fb.each #=> #<Enumerator: #<FizzBuzz:0x007fc5139e5540 @start=1, @stop=15>:each>
198
+ * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xf722f8ec @stop=15, @start=1>
199
+ * fb.each #=> #<Enumerator: #<FizzBuzz:0x007fc513 @start=1, @stop=15>:each>
219
200
  *
220
201
  * Example:
221
202
  *
222
- * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xf722f8ec @stop=15, @start=1>
203
+ * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xf722f8ec @stop=15, @start=1>
223
204
  * fb.each {|value| puts "Got #{value}" }
224
205
  *
225
206
  * Produces:
@@ -251,7 +232,7 @@ rb_fb_enumerator(VALUE object)
251
232
  /*
252
233
  * call-seq:
253
234
  * fizzbuzz.reverse_each {|value| block } -> self
254
- * fizzbuzz.reverse_each -> an Enumerator
235
+ * fizzbuzz.reverse_each -> an Enumerator
255
236
  *
256
237
  * Calls the block _once_ for each subsequent value for a given range
257
238
  * from +start+ to +stop+ in an <i>reverse order</i>, passing the value
@@ -261,12 +242,12 @@ rb_fb_enumerator(VALUE object)
261
242
  *
262
243
  * Example:
263
244
  *
264
- * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xf722f8ec @stop=15, @start=1>
265
- * fb.each #=> #<Enumerator: #<FizzBuzz:0x007fc513a0de00 @start=1, @stop=15>:reverse_each>
245
+ * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xf722f8ec @stop=15, @start=1>
246
+ * fb.each #=> #<Enumerator: #<FizzBuzz:0x007fc513 @start=1, @stop=15>:reverse_each>
266
247
  *
267
248
  * Example:
268
249
  *
269
- * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xb7308664 @stop=15, @start=1>
250
+ * fb = FizzBuzz.new(1, 15) #=> #<FizzBuzz:0xb7308664 @stop=15, @start=1>
270
251
  * fb.reverse_each {|value| puts "Got #{value}" }
271
252
  *
272
253
  * Produces:
@@ -309,16 +290,15 @@ rb_fb_reverse_enumerator(VALUE object)
309
290
  * FizzBuzz.is_fizz?(15) #=> false
310
291
  *
311
292
  * Will raise a <i>FizzBuzz::TypeError</i> exception if given value is not
312
- * an _Fixnum_ or _Bignum_ type.
293
+ * a _Fixnum_ or _Bignum_ type, or an _Integer_ type starting from Ruby
294
+ * version 2.4 onwards.
313
295
  *
314
296
  * See also: FizzBuzz::[]
315
297
  */
316
298
  VALUE
317
- rb_fb_is_fizz(VALUE object, VALUE value)
299
+ rb_fb_is_fizz(RB_UNUSED_VAR(VALUE object), VALUE value)
318
300
  {
319
- UNUSED(object);
320
301
  CHECK_TYPE(value, error(E_INVALID_TYPE));
321
-
322
302
  return CBOOL2RVAL(IS_FIZZ(value));
323
303
  }
324
304
 
@@ -336,16 +316,15 @@ rb_fb_is_fizz(VALUE object, VALUE value)
336
316
  * FizzBuzz.is_buzz?(15) #=> false
337
317
  *
338
318
  * Will raise a <i>FizzBuzz::TypeError</i> exception if given value is not
339
- * an _Fixnum_ or _Bignum_ type.
319
+ * a _Fixnum_ or _Bignum_ type, or an _Integer_ type starting from Ruby
320
+ * version 2.4 onwards.
340
321
  *
341
322
  * See also: FizzBuzz::[]
342
323
  */
343
324
  VALUE
344
- rb_fb_is_buzz(VALUE object, VALUE value)
325
+ rb_fb_is_buzz(RB_UNUSED_VAR(VALUE object), VALUE value)
345
326
  {
346
- UNUSED(object);
347
327
  CHECK_TYPE(value, error(E_INVALID_TYPE));
348
-
349
328
  return CBOOL2RVAL(IS_BUZZ(value));
350
329
  }
351
330
 
@@ -358,21 +337,20 @@ rb_fb_is_buzz(VALUE object, VALUE value)
358
337
  *
359
338
  * Example:
360
339
  *
361
- * FizzBuzz.is_fizzbuzz?(3) #=> false
362
- * FizzBuzz.is_fizzbuzz?(5) #=> false
340
+ * FizzBuzz.is_fizzbuzz?(3) #=> false
341
+ * FizzBuzz.is_fizzbuzz?(5) #=> false
363
342
  * FizzBuzz.is_fizzbuzz?(15) #=> true
364
343
  *
365
344
  * Will raise a <i>FizzBuzz::TypeError</i> exception if given value is not
366
- * an _Fixnum_ or _Bignum_ type.
345
+ * a _Fixnum_ or _Bignum_ type, or an _Integer_ type starting from Ruby
346
+ * version 2.4 onwards.
367
347
  *
368
348
  * See also: FizzBuzz::[]
369
349
  */
370
350
  VALUE
371
- rb_fb_is_fizzbuzz(VALUE object, VALUE value)
351
+ rb_fb_is_fizzbuzz(RB_UNUSED_VAR(VALUE object), VALUE value)
372
352
  {
373
- UNUSED(object);
374
353
  CHECK_TYPE(value, error(E_INVALID_TYPE));
375
-
376
354
  return CBOOL2RVAL(IS_FIZZBUZZ(value));
377
355
  }
378
356
 
@@ -393,82 +371,71 @@ rb_fb_is_fizzbuzz(VALUE object, VALUE value)
393
371
  * FizzBuzz[15] #=> "FizzBuzz"
394
372
  *
395
373
  * Will raise a <i>FizzBuzz::TypeError</i> exception if given value is not
396
- * an _Fixnum_ or _Bignum_ type.
374
+ * a _Fixnum_ or _Bignum_ type, or an _Integer_ type starting from Ruby
375
+ * version 2.4 onwards.
397
376
  *
398
377
  * See also: FizzBuzz::is_fizz?, FizzBuzz::is_buzz? and FizzBuzz::is_fizzbuzz?
399
378
  */
400
379
  VALUE
401
- rb_fb_square(VALUE object, VALUE value)
380
+ rb_fb_square(RB_UNUSED_VAR(VALUE object), VALUE value)
402
381
  {
403
- UNUSED(object);
404
382
  CHECK_TYPE(value, error(E_INVALID_TYPE));
405
-
406
383
  return fizzbuzz_evaluate(value);
407
384
  }
408
385
 
409
- /* :enddoc: */
410
-
411
386
  static VALUE
412
387
  fizzbuzz_evaluate(VALUE value)
413
388
  {
414
- int8_t score;
389
+ int score;
415
390
 
416
- if (ZERO_P(value)) {
417
- return value;
418
- }
391
+ if (ZERO_P(value))
392
+ return value;
419
393
 
420
394
  score = SCORE_VALUE(value);
395
+
421
396
  assert((score >= 0 && score <= 3) && \
422
- "Score value out of bounds, must be between 0 and 3 inclusive");
397
+ "Score value out of bounds, must be between 0 and 3 inclusive");
423
398
 
424
- /*
425
- * The CSTR2RVAL macro uses rb_str_new2(const char *) which is
426
- * rather slow due to all the heavy lifting done internally by
427
- * str_new0(VALUE, const char *, long, int) to allocate space
428
- * for the new String object, etc.
429
- */
430
- return score < 1 ? value : CSTR2RVAL(word(score));
399
+ return score < 1 ? value : word(score);
431
400
  }
432
401
 
433
402
  static VALUE
434
- fizzbuzz_values(VALUE object, fizzbuzz_return_t type, fizzbuzz_direction_t direction)
403
+ fizzbuzz_values(VALUE object, fizzbuzz_return_t type,
404
+ fizzbuzz_direction_t direction)
435
405
  {
406
+ int forward = LOOP_FORWARD(direction);
407
+
436
408
  VALUE i = Qnil;
437
409
 
438
410
  VALUE array = Qnil;
439
411
  VALUE value = Qnil;
440
412
 
441
413
  VALUE start = rb_ivar_get(object, id_at_start);
442
- VALUE stop = rb_ivar_get(object, id_at_stop);
414
+ VALUE stop = rb_ivar_get(object, id_at_stop);
443
415
 
444
- if (WANT_ARRAY(type)) {
445
- array = rb_ary_new();
446
- }
447
- else {
448
- RETURN_ENUMERATOR(object, 0, 0);
449
- }
416
+ if (WANT_ARRAY(type))
417
+ array = rb_ary_new();
418
+ else
419
+ RETURN_ENUMERATOR(object, 0, 0);
450
420
 
451
- if (LOOP_FORWARD(direction)) {
452
- for (i = start; LESS_EQUAL(i, stop); i = INCREASE(i)) {
453
- value = fizzbuzz_evaluate(i);
454
- WANT_ARRAY(type) ? rb_ary_push(array, value) : rb_yield(value);
455
- }
456
- }
457
- else {
458
- for (i = stop; GREATER_EQUAL(i, start); i = DECREASE(i)) {
459
- value = fizzbuzz_evaluate(i);
460
- WANT_ARRAY(type) ? rb_ary_push(array, value) : rb_yield(value);
461
- }
421
+ i = forward ? start : stop;
422
+
423
+ while (RB_LIKELY(forward ? LESS_EQUAL(i, stop) : GREATER_EQUAL(i, start))) {
424
+ value = fizzbuzz_evaluate(i);
425
+ WANT_ARRAY(type) ? rb_ary_push(array, value) : rb_yield(value);
426
+ i = forward ? INCREASE(i) : DECREASE(i);
462
427
  }
463
428
 
429
+ RB_GC_GUARD(array);
430
+ RB_GC_GUARD(value);
431
+
464
432
  return WANT_ARRAY(type) ? array : object;
465
433
  }
466
434
 
467
435
  static VALUE
468
436
  fizzbuzz_exception_wrapper(VALUE value)
469
437
  {
470
- fizzbuzz_exception_t *e = (struct fizzbuzz_exception *)value;
471
-
438
+ fizzbuzz_exception_t *e = (fizzbuzz_exception_t *)value;
472
439
  return rb_exc_new2(e->klass, e->message);
473
440
  }
474
441
 
@@ -479,13 +446,14 @@ fizzbuzz_exception(void *data)
479
446
  VALUE object = Qnil;
480
447
 
481
448
  fizzbuzz_exception_t *e = data;
482
- assert(e != NULL && "Must be a valid pointer to `fizzbuzz_exception_t' type");
449
+
450
+ assert(e != NULL && \
451
+ "Must be a valid pointer to `fizzbuzz_exception_t' type");
483
452
 
484
453
  object = rb_protect(fizzbuzz_exception_wrapper, (VALUE)e, &exception);
485
454
 
486
- if (exception) {
487
- rb_jump_tag(exception);
488
- }
455
+ if (exception)
456
+ rb_jump_tag(exception);
489
457
 
490
458
  rb_iv_set(object, "@start", e->start);
491
459
  rb_iv_set(object, "@stop", e->stop);
@@ -507,7 +475,8 @@ fizzbuzz_type_error(VALUE klass, const char *message)
507
475
  }
508
476
 
509
477
  static VALUE
510
- fizzbuzz_range_error(VALUE klass, VALUE start, VALUE stop, const char *message)
478
+ fizzbuzz_range_error(VALUE klass, VALUE start, VALUE stop,
479
+ const char *message)
511
480
  {
512
481
  fizzbuzz_exception_t e;
513
482
 
@@ -523,11 +492,27 @@ void
523
492
  Init_fizzbuzz(void)
524
493
  {
525
494
  id_at_start = rb_intern("@start");
526
- id_at_stop = rb_intern("@stop");
495
+ id_at_stop = rb_intern("@stop");
527
496
 
528
497
  rb_cFizzBuzz = rb_define_class("FizzBuzz", rb_cObject);
529
498
  rb_include_module(rb_cFizzBuzz, rb_mEnumerable);
530
499
 
500
+ /*
501
+ * The CSTR2RVAL macro uses rb_str_new2(const char *) which is
502
+ * rather slow due to all the heavy lifting done internally by
503
+ * str_new0(VALUE, const char *, long, int) to allocate space
504
+ * for the new String object, etc.
505
+ */
506
+ rb_define_const(rb_cFizzBuzz, "WORD_FIZZ", CSTR2RVAL("Fizz"));
507
+ rb_define_const(rb_cFizzBuzz, "WORD_BUZZ", CSTR2RVAL("Buzz"));
508
+ rb_define_const(rb_cFizzBuzz, "WORD_FIZZBUZZ", CSTR2RVAL("FizzBuzz"));
509
+
510
+ if (NIL_P(words[0])) {
511
+ words[0] = rb_str_freeze(rb_const_get(rb_cFizzBuzz, rb_intern("WORD_FIZZ")));
512
+ words[1] = rb_str_freeze(rb_const_get(rb_cFizzBuzz, rb_intern("WORD_BUZZ")));
513
+ words[2] = rb_str_freeze(rb_const_get(rb_cFizzBuzz, rb_intern("WORD_FIZZBUZZ")));
514
+ }
515
+
531
516
  /*
532
517
  * Raised when _FizzBuzz_ encounters an error.
533
518
  */
@@ -577,5 +562,3 @@ Init_fizzbuzz(void)
577
562
  #if defined(__cplusplus)
578
563
  }
579
564
  #endif
580
-
581
- /* vim: set ts=8 sw=4 sts=2 et : */