2015-01-01から1年間の記事一覧

Ruby で #method_added が定義されてるモジュールを複数 mixin してみた。続き

Ruby で #method_added が定義されてるモジュールを複数 mixin してみた。続き Twitter で教えてもらって super を使えば元のメソッドを呼びだせるみたい。 [コード] module A def method_added name p "A#method_added: #{name}" end end module B def meth…

Ruby で #method_added が定義されてるモジュールを複数 mixin してみた

Ruby で #method_added が定義されてるモジュールを複数 mixin してみたらどうなるのか試してみた。 [コード] module A def method_added name p "A#method_added: #{name}" end end module B def method_added name p "B#method_added: #{name}" end end cl…

Ruby でメソッドを薄くラップする

みたいな機能が欲しかったので書いてみた。 [コード] module MethodWrapper def wrap name, &block prepend(Module.new do define_method name do super_ = proc { super() } Object.new.instance_eval do define_singleton_method :super_ do super_.() end…

Ruby の正規表現の比較で改行コードを配慮する

さて、次のようなコードの場合、改行コードを考慮せずに \n までしか返ってきません。 # マッチした文字列を取得したい "homu\nmami" =~ /^h(.*)/ && $1 # => "omu" こういう場合に改行コードも含めて欲しい場合は正規表現のリテラルに /m を追加します。 "h…

Ruby でメソッドが追加された時に呼び出されるメソッドのまとめ

大まかに .singleton_method_added、.method_added, #singleton_method_added の3つを使い分ければいい感じですかね。 [コード] class X # クラスメソッドを定義した時に呼び出される def self.singleton_method_added name p "class method : #{name}" end …

Ruby でクラスメソッドが定義された時に処理をフックする

Ruby でクラスメソッド、つまりクラスオブジェクトに対して特異メソッドが定義された時に処理をフックしたい場合は .singleton_method_added メソッドを『クラスメソッド』として定義します。 [コード] class X # インスタンスメソッドに singleton_method_a…

Ruby で特異メソッドを定義した際に処理をフックする

Ruby で特異メソッドを定義した際に処理をフックする場合、『インスタンスメソッド』に #singleton_method_added を定義します。 [コード] class X # インスタンスメソッドに singleton_method_added を追加する def singleton_method_added name p name end…

Ruby でインスタンスメソッドが定義された時に処理をフックする

インスタンスメソッドが定義された時に処理をフックしたい場合、『クラスメソッド』に #method_added を定義します。 [コード] class X # クラスメソッドに method_added を追加する def self.method_added name p name end # インスタンスメソッドを定義し…

Ruby で define_method で定義した中から super を呼び出す

次のようなコードで define_method 内から super を呼びだそうとしたらエラーになりました。 module M define_method :homu do p :superhomu # ここで元のメソッドを呼び出したかった super end end class X prepend M def homu p :homu end end X.new.homu …

Ruby のヒアドキュメントの識別子で記号を使う

ヒアドキュメントの識別子で記号を使用したい場合、文字列リテラルで定義することで記号を使用することができます。 str = <<"==EOS==" homu mami mado ==EOS== p str # => "homu\nmami\nmado\n" 便利そう。

C++ の private メンバにアクセスする手段

C++

特に面白みもないんだけどメンバ変数のポインタがわかっていればアクセスすることは可能よね、と。 [コード] #include <iostream> struct X{ auto get_value_ptr(){ return &X::value; } private: int value = 42; }; int main(){ X x; // error // x.value; auto valu</iostream>…

Vim で長すぎて表示されない行を表示する

Vim

いまさらですが 'display' オプションの存在を知りました。 Vuim では1行が長すぎて表示しきれない場合、 と、いうような表示になるんですが、display=lastline というような設定を行うことで このように途中のまでを表示してくれるようになります。 今まで…

Ruby でインスタンスメソッドを定義する手段

特定のクラスオブジェクトに対してインスタンスメソッドを定義したい場合にどういう手段があるのかまとめてみた。 クラス定義から定義する 多分普通のやり方。 単純にクラス定義時にメソッドを定義します。 class String def twice self + self end end "hom…

Ruby でトップレベルで定義したローカル変数は他のファイルからは参照されない

てっきりトップレベルで定義した変数はグローバル変数扱いで他のファイルからでも参照できるのかと思ったんですが、そういうことはないんですねー。 [a.rb] def a_func :a_func end @a = 42 a = 10 [b.rb] require_relative "./a" # メソッドやインスタンス…

今日教えてもらった Ruby の意味不明なコード

コード eval "a = 42" a = p a 出力 42 さて、これの動作が理解できる Rubyist はどれぐらいいるのだろうか。 なお、詳しい解説は某ももんが氏がしてくれるはず。

Ruby の eval でローカル変数に代入したかった

Ruby の #eval ではローカル変数を定義することはできませんが、インスタンス変数は定義する事ができるので、それを代替として使用することは可能です。 # ローカル変数定義はできない # eval "a = 42" # インスタンス変数は定義できる eval "@a = 42" p @a …

Ruby の eval メソッドでローカル変数定義はできない

次のように #eval メソッドでローカル変数を定義した場合、外からは参照することができない。 eval "a = 42" p a + a # => error: undefined local variable or method `a' for main:Object (NameError) これは expr 内のローカル変数の扱いがブロックと同じ…

Ruby で無限ループする

無限ループというと while 1 みたいな構文で行うことが多いですが、Ruby では #loop メソッドを利用する事ができます。 # ループしたい処理をブロック内に記述する # 終了したい場合は break で抜ける loop { n = rand(0..10) puts n if n == 0 break end } …

Ruby の #freeze メソッドで凍結したオブジェクトを元に戻すことはできない

知らなかったので覚書。 Ruby では #freeze メソッドを使用して、破壊的なメソッドの呼び出しを抑制する事ができます。 s = "homu" s.freeze s.upcase! # error: `upcase!': can't modify frozen String (RuntimeError) この #freeze メソッドで不変にしたオ…

Ruby の r サフィックス

Ruby で 1/2r みたいな式を見かけたので調べてみた。 2r という風に数値に r サフィックスをつけることで Rational(2/1) という風な定義になるみたい。 なので最初の式は 1 / Rational(2/1) となる。 また、このサフィックスは Ruby 2.1 から導入された模様…

C言語で任意の区切り文字で文字列を分割する

string.h の strtok() を使用すると任意の区切り文字で文字列を分割する事ができるんですが、その使い方が結構ぶっ飛んでて面白かった。 [コード] #include <stdio.h> #include <string.h> int main(){ char str[] = "homu,mami,mado"; char* tp; /* 最初に見つかった区切り文字</string.h></stdio.h>…

Ubuntu で新し目の boost をインストールしたかった

自分でビルドするのがだるかったので色々と調べてみた結果、以下のパッケージを使うのが一番手っ取り早かった。 Ubuntu – Details of package libboost1.58-dev in wily boost の最新版は 1.59 だけど、ひとまずこれでいいかなぁ。

LLVM/Clang 3.7 がリリース

いつの間にか 3.7 がリリースされていました。 リリースノートは以下の通り LLVM 3.7 Release Notes LLVM 3.7 documentation

Boost.TypeErasure のミニマム実装

その昔に書いたコードを発掘したので載せてみるなど。 このコードは Boost.TypeErasure がリリースされた頃に書いたので、現在の実装はまた別のものになっているかも知れない。 [コード] #include <iostream> #include <boost/any.hpp> template<typename Concept, typename T> struct adapter{ static void apply(bo</typename></boost/any.hpp></iostream>…

C++ で std::vector<派生クラス> から std::vector<基底クラス> に変換する

C++

さて、C++ では次のような std::vector<派生クラス> から std::vector<基底クラス> への 暗黙的な変換はできません。 struct base{ }; struct derived : base{ }; std::vector<derived*> ary; // base は derived の基底クラスなので変換を期待するが、こういう変換は</derived*>…

std::vector で参照を保持したい

C++

std::vector<T&> みたいに std::vector で参照値を保持したい事があると思いますが、これはコンパイルエラーになってしまいます。 この問題を回避したい場合は、C++11 で追加された std::reference_wrapper を利用する事ができます。 [コード] #include <vector> #includ</vector></t&>…

std::reference_wrapper の参照元に T 型の値を代入する

C++

std::reference_wrapper<T> は std::ref() 等で返ってくるクラスなんですが、参照元に T 型の値を代入するときにちょっと気になったので覚書。 さて、次のように std::reference_wrapper<int> で保持している参照元に対して整数を代入する場合、コンパイルエラーにな</int></t>…

Ruby の Class.new で生成したオブジェクトを受け取る変数名によって挙動が変わる

どういうことかというと大文字から始まる変数名と小文字から始まる変数名では #class で返ってくる値が違いました。 X = Class.new X.new.class # => X x = Class.new x.new.class # => #<Class:0x000000016871c0> Ruby キモい(確信</class:0x000000016871c0>

unite.vim でサブアクション的なものを定義する

Vim

元々は本体に要望していた機能だったんですが、最近簡単に定義できる方法を思いついたので書いておきます。 概要としては、デフォルトアクションとは別に source で共通したキーマッピングのアクションがほしいというものでした。 (<Leader><CR> を入力した時に source-f</cr></leader>…

C++ では void* から他のポインタ型へ暗黙的に変換できない

C++

今まで知らなかったので覚書。 C++ では void* 型から他のポインタ型へ暗黙的に変換することはできない。 なので、次のようなコードはエラーになる。 void* vp; // error: cannot initialize a variable of type 'int *' with an lvalue of type 'void *'; i…