なんと、C拡張でモンキーパッチまで可能だとは!
ここが参考になりました。
前記事の C拡張をオープンクラスで実現します。Bundler を使っています。ソースは以下。
#include "utilsc.h" long gcd(long x, long y) { long tmp; if (x < y) {tmp = x; x = y; y = tmp;} if (!y) return x; return gcd(y, x % y); } VALUE totient(VALUE self) { int a; long i, se; a = 0; se = FIX2LONG(self); for (i = 1; i < se; i++) { if (gcd(se, i) == 1) a++; } return INT2FIX(a); } void Init_utilsc(void){ VALUE fix; fix = rb_const_get(rb_cObject, rb_intern("Fixnum")); rb_define_method(fix, "totient", totient, 0); }
上は以下の Ruby コードとほぼ同等です。require 'utilsc'
で実現します。utilsc はモジュールでも何でもないのですね。
class Fixnum def totient a = 0 1.upto(self - 1) {|i| a += 1 if gcd(i) == 1} return a end end
サンプルコード。
require 'bundler/setup' require 'utilsc' 2.upto(10) {|i| puts i.totient}
なお、GitHub で野良 Gem を作っているときに
Agent admitted failure to sign using the key.
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
というエラーがでました。これは
$ eval "$(ssh-agent -s)" $ ssh-add ~/.ssh/id_rsa
でパスフレーズを打ち込んで解決。
$ ssh -T git@github.com
で確認。
それから、野良Gem 作成はここがわかりやすい。