Ruby

Ruby で xlsx を編集する

Ruby で既存のエクセルファイルを編集したかったので試してみた。 Ruby でエクセルファイルを扱う手段(gem)はいくつかあるが今回は、 .xlsx ファイルの読み込み .xlsx ファイルの書き込み セルの結合 を行いたかったので RubyXL を使うことにした。 余談 …

今更聞けない! Ruby の継承と mixin の概念を継承リストから学ぶ

Ruby を学ぶ上で継承と mixin の概念を理解することはとても重要である。 しかし、このあたりの仕組みを学ぼうとすると、include や prepend、特異クラスや特異メソッドなどという様々な機能を理解する必要がありとても複雑である。 そこで本記事は『継承リ…

Ruby でメソッドの呼び出し元の情報を取得する

例えば、次のコードのように『A.hoge の呼び出し元の情報』を取得したいことがあります。 module A def self.hoge # 呼び出し元である X オブジェクトを取得したい end end class X A.hoge end 標準の範囲だとできなさそうだったんですが、binding_of_caller…

Ruby で任意のクラスが特異クラスかどうか判定する

Ruby で任意のクラスが特異クラスか判定しなーと思ってあれこれ考えていたんですが、そもそも Module#singleton_class? がすでに存在していました。 class X end p X.singleton_class? # => false p X.singleton_class.singleton_class? # => true p X.new.s…

Ruby で内部クラスを private にする

Ruby で内部クラスを private にする場合どうするのがよいかと思っていたんですが private_constant を使うのがいいみたい。 private_constant があるのでそれを使えばそれっぽい気がします https://t.co/79ySXXyQ7l— Pocke(ぽっけ) (@p_ck_) 2017年8月8日 c…

Ruby の hook メソッド一覧

Ruby から呼ばれる hook メソッドの一覧が欲しかったので Ruby 2.4 時点で定義されているメソッドをまとめてみました。 他にもあればコメント等で教えていただけると助かります。 Class クラス #inherited クラスのサブクラスが定義されたとき Module クラス…

Ruby の (1..5) と (1...5) の違い

前者は使っていたけど、後者は知らなかかったので覚書。 範囲演算子 .. を使用した場合は終端を含み、... を使用した場合は終端を含みません。 p (1..5).to_a # => [1, 2, 3, 4, 5] p (1...5).to_a # => [1, 2, 3, 4]

Ruby の () の戻り値

Ruby だと () の戻り値は nil になるらしい。 p () # => nil p ().nil? # true ほぼ使うことはないだろうけど知らなかった(そもそも () だけ評価出来ると思ってなかった。 ちなみに #call が呼び出されるわけではない。 class X def call "call" end def fu…

Ruby で任意の異なるクラスのオブジェクトを #uniq するときの注意

元ネタ Rubyむずい…うむむむむむむむうむ[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ https://t.co/buooxLKDHW— 異常者 (@h1manoa) 2017年6月8日 と、いうことでちょっとやってみたら見事にハマったので覚書 元のコード class Hoge def initialize(num) @num = num end d…

RSpec で pending しても before :context が呼ばれてしまう

結果だけ先に書いてしまいますが『pending しているスコープで before :context を定義すると before のブロックが呼ばれます』。 どういうことかというと次のように before :context 内で例外が発生した場合、テストが失敗してしまいます。 describe X do #…

Ruby の Method#=== が定義されていないのでつらい問題

Method#=== が定義されていなくてつらい問題です。 Proc#=== Proc オブジェクトでは #call で評価することが出来ますが、そのエイリアスとして #=== が存在します。 upcase = proc { |a| a.upcase } upcase.call "homu" # => "HOMU" upcase === "mami" # => …

Ruby で mixin したモジュールを削除する gem をつくった

Ruby でメタプログラミングをやっているとどうしても『mixin したモジュールを削除したい』という欲求にかられるのでつくりました。 インストール $ gem install unmixer 使い方 require "unmixer" # Unmixer は refinements を使用してるので using して使…

Ruby 2.4 で refinements の制限が緩和された

さて、先日 Ruby 2.4 がリリースされました。 Ruby 2.4.0 リリース [refinements の制限を緩和] Ruby 2.4 では refinements の制限が緩和され、#send からも refine されているメソッドが呼び出せるようになりました。 class X; end module Ex refine X do d…

【Ruby Advent Calendar 2016 1日目】 Ruby でブロックを簡潔に定義する

Ruby Advent Calendar 2016の1日目の記事になります。 わたしはあまり Rails と言ったフレームワークや Ruby がよく利用されてる Web 界隈には詳しくはないので、本記事は Ruby という言語に関するネタになります。 [Ruby といえば] さて、表題のブロックで…

Ruby の Hash でキーが存在しなかった時の初期値を設定する

table = [] table[index] ||= [] table[index] << name みたいに [] で初期化するようなコードは table = Hash.new { |hash, key| hash[key] = [] } table[index] << name という風に .new に渡すブロック内で値を初期化することができる。

Ruby の正規表現でパスをいい感じに記述する

例えば、Ruby の正規表現内でパスを含む際に /^\/path\/to\/hoge.*/ みたいに書くことがあると思います。 この時にパスの / は \/ という風にエスケープして記述する必要があります。 [%r を使う] こういう時に %r を使うと綺麗に書くことが出来ます。 %r{^/…

#tap で任意の戻り値を返す

以前も書いたような気がしますが、#tap で任意の戻り値を返したい場合は break を使用します。 # #tap は通常自身を返す p 10.tap { |myself| myself + 32 } # => 10 # #tap で戻り値を返したい場合は break を使用する p 10.tap { |myself| break myself + …

Ruby の Symbol#to_proc に引数を渡す拡張

『[1,2,16].map(&:to_s(16)) みたいにかきたいよねー』というやつ。 class Symbol def call *args, &block proc { |myself| myself.send self, *args, &block } end end p [1, 2, 16].map(&:to_s.(16)) # => ["1", "2", "10"] #call を定義してこういう風に…

Ruby で alias_method の元の名前を取得する

RUby で alias_method した元の名前を取得したい場合 Method#original_name で取得することが出来ます。 class X def homu "homu" end alias_method :mami, :homu alias_method :mado, :mami end x = X.new p x.method(:homu).original_name # => :homu p x.…

RSpec で指定した行のテストのみ実行する

rspec に渡すファイル名の末尾に ファイル名:行番号 と指定すればその行番号のテストのみが実行されます。 $ rspec path/to/hoge_spec.rb:42 これで42行目に関連してるテストが実行されます。

rake spec で特定のファイルのテストを実行する

rake spec で特定のファイルのテストを実行したい場合、次のようにして SPEC にファイル名を設定して実行します。 $ SPEC=spec/path/to/hoge_spec.rb rake spec

Ruby の binding オブジェクトからローカル変数にアクセスする

Binding#local_variable_get でローカル変数にアクセスする事が出来ます。 def func a, b add = a + b # このメソッド内のコンテキストを返す binding end context = func 1, 2 # #local_variable_get でコンテキストの変数を取得する p context.local_varia…

Ruby の binding オブジェクトと eval()

Ruby では現在のスコープのコンテキストを bindig オブジェクトとして扱う事が出来ます。 def func a, b add = a + b # このメソッド内のコンテキストを返す binding end p func 1, 2 # => #<Binding:0x00000000c0fe18> [binding オブジェクトと #eval()] bindig の利用方法はいくつか</binding:0x00000000c0fe18>…

RSpec で not_change マッチャを定義する

通常、Rspec で『変更されないことを検証する』場合、change マッチャを使用します。 # subject を呼び出しても hoge が変更されないことを検証する it { is_expected.not_to change{ hoge } } [not_change マッチャを定義する] 上記のコードでも問題ないの…

Ruby の ObjectSpace を利用して、オブジェクト名からクラスオブジェクトを探す

Ruby で例えば "String" という文字列からその名前のクラスオブジェクトを取得したい場合があるとします。 そういう場合は ObjectSpace から逆算して検出することができます。 # クラスオブジェクトの一覧を取得する classes =ObjectSpace.each_object(::Cla…

Ruby の refinements で特異メソッドを定義する時の注意

さて、次のようにクラスオブジェクトに対して特異メソッドを定義するとエラーになります。 module StringEx refine String do class << self def homu "homu" end end end end using StringEx # Error: undefined method `homu' for String:Class (NoMethodE…

Ruby で無名スコープみたいなのを記述する

C++ では {} で任意の箇所に無名スコープをつくることができます。 int value = 10; { int count = 3; // スコープの外の変数にアクセスできる value += count; } // スコープの中で定義した変数はスコープ外でアクセスはできない // value = count; Ruby の…

Ruby で nil.to_i の戻り値

某所で聞いたので覚書。 Ruby の nil を #to_i で数値に変換すると 0 が返ってくる。 nil.to_i # => 0 そりゃそうなんだけど、Ruby で nil が 0 になるのはなんか不思議

RSpec の have_attributes マッチャ

RSpec の have_attributes マッチャは『オブジェクトの属性(プロパティ)を検証する』マッチャになります。 例えば、 it { expect(10.to_s).to eq("10") } it { expect(10.positive?).to eq(true) } というようなテストが # メソッド名と戻り値の Hash を渡…

Ruby の &. と #try の違い

Ruby 2.3 で Safe Navigation Operator(&.)という新しい演算子が追加されました。 これは obj&.to_i という風にメソッド呼び出しのように使い、レシーバが nil の場合に nil を返します。 10&.to_s # => "10" nil&.to_s # nil このように nil チェックするこ…