読者です 読者をやめる 読者になる 読者になる

Ruby

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 チェックするこ…

RSpec の is_expected で raise_error を検知したかった

RSpec では subject と is_expected を利用して次のようにテストを書くことが出来ます。 context "test" do subject { 42 } # is_expected の内部で subject が呼び出される it { is_expected.to eq(42) } end raise_error を使いたかった 次のように raise …

Ruby 2.3 の Numeric#positive? と Numeric#negative?

Ruby 2.3 から Numeric#positive? と Numeric#negative? が追加されました。 これはそれぞれ self > 0 と self < 0 を返します。 p 42.positive? # => true p -42.positive? # => fasle p 42.negative? # => false p -42.negative? # => true p 0.positive? …

Ruby で -"42" としたら -42 が返ってきてほしい

class String def -@ -to_i end end p -"42" # => -42 お気持ちです。

Ruby の #tap の面白い挙動

Ruby の #tap はレシーバをブロック引数に渡して、レシーバ自身を返すメソッドです。 x = 42 p x.tap{ |n| p n + n } # output: # 84 # 42 ブロック内でレシーバ自身を書き換えても書き換える前の値が返ってくる この #tap の面白い挙動なんですが、ブロック…

Ruby で実行マシンのプロセス数を取得する

Ruby 2.2.0 で Etc.#nprocessors というメソッドが追加されたのでそれを使えばよいみたい。 require "etc" p Etc.nprocessors # => 2 手元の環境だと2コアしかないのできびしい。

Ruby の func [] と func[] の違い

Ruby ではメソッドの呼び出しに () を省略することができるので、次のような奇妙なコードを記述することが出来ます。 def func *ary ["homu", "mami", "mado"] end p func [1] # => ["homu", "mami", "mado"] p func[1] # => "mami" これは func [1] が func…

rbenv で gem install したコマンドが呼び出せなかった場合の対処

rbenv で Ruby を管理使用としたんですが、何故か bundle コマンドが使えませんでした。 そういう場合は以下のように rehash を使うと改善されるみたいです。 $ rbenv rehash

Ruby で画像を半分に分割

横に長い画像を半分に分割したかったので Ruby の mini_magick を使って書いてみた。 require "mini_magick" def cut_image src left = MiniMagick::Image.open src return left, nil if left[:width] < left[:height] width = left[:width] / 2 right = Min…

ruboty-vimhelp つくった

ruboty から vim を help できる ruboty-vimhelp をつくりました。 github.com ruboty :help {keyword} で Vim の help が出力されます。

ruboty-tanzaku つくった

つくりました。 github.com 使い方 > ruboty tanzaku ねがいごと ┏┷☆ ┃ね┃ ┃が┃ ┃い┃ ┃ご┃ ┃と┃ ★━┛

Ruboty で RUBOTY_NAME を無視するプラグインをつくった

最近 Ruby で拡張することができる Bot フレームワークの Ruboty にはまっています。 Ruboty については以下に詳しく書かれています Ruboty って何?どうやって動かすの? Hubot と何が違うの?どっちを使えばいいの? #ruboty #chatops - Qiita [RUBOTY_NAM…

Ruby の正規表現で名前付きキャプチャするときの注意

Ruby の正規表現で名前付きキャプチャを行う時、Regexp#match ではなくて Regexp#=~ を使用することで『ローカル変数』として定義することも出来ます。 /(?<hour>\d{2}):(?<minus>\d{2}):(?<second>\d{2})/ =~ "11:22:33" p hour # => "11" p minus # => "22" p second # => "33" </second></minus></hour>…

Ruby 正規表現で名前付きキャプチャ

Ruby の正規表現で (?<name>pat) と記述することで、名前付きキャプチャを行うことが出来ます。 キャプチャした文字列のデータは Regexp#match で取得する事が出来ます。 timep = /(?<hour>\d{2}):(?<minus>\d{2}):(?<second>\d{2})/ m = timep.match "11:22:33" p m[:hour] # => "11" p</second></minus></hour></name>…

Gemfile で github から gem を読みこむ

Gemfile では次のようにして github からも gem を読みこむことが出来ます。 gem "kiriban", github: "osyo-manga/gem-kiriban" この時にリポジトリ名と gem の名前が異なっていても問題はないです。

line-bot-sdk-ruby で proxy を設定したかった

Ruby で LINE の bot を作るときに line-bot-sdk-rubyが利用出来ます。 GitHub - line/line-bot-sdk-ruby: SDK of the LINE BOT API Trial for Ruby これを利用すれば、比較的簡単に LINE の bot を作ることが出来ます。 [proxy を設定する] LINE の bot を …

Ruby でメソッドを多重定義するためのライブラリをつくった

まあつくったのは結構前なんですが、つくりました。 Ruby は動的型付け言語なので、静的型付けのような型によるメソッドの多重定義は出来ないんですが、このライブラリによって静的型付けのようなメソッドの多重定義を実現する事ができます。 require "stitc…

Ruby でキリバンをチェックするライブラリつくった

ほしかったのでつくった。 インストール $ gem install kiriban 使い方 require "kiriban" # キリバン p 10000.kiriban? p 11111.kiriban? p 12345.kiriban? p 12321.kiriban? # ゼロバン(先頭以外が 0) p 10000.zeroban? # ゾロバン(同じ数字) p 11111.…

Ruby で C言語ライクな enum を行うライブラリをつくった

Ruby で C言語ライクな enum をするライブラリをつくった。 github - https://github.com/osyo-manga/gem-cstyle_enum インストール $ gem install cstyle_enum 使い方 require "cstyle_enum" class Color # enum or cstyle_enum Colors = enum { RED GREEN …

Ruby で暗黙のブロックパラメータを使うための gem をつくった

Ruby で暗黙のブロックパラメータを使うための gem をつくりました。 元ネタ : Rubyのブロックつらい問題を解決する暗黙のブロックパラメータ - Qiita github : osyo-manga/gem-use_arguments インストール $ gem install use_arguments 定義される暗黙のブ…

Ruby でメタプログラミング的にフィボナッチ数列を求める

Ruby でフィボナッチ数列を求めるメタプログラミングを書いてみた。 class Fib def call n __send__ "_#{n}" end def method_missing name, *args n = name[/_(\d+)/, 1].to_i if n > 1 n = call(n - 2) + call(n - 1) end define_singleton_method(name) { …

Ruby で refinements で mixin したメソッドから別のメソッドを呼び出す

さて、Ruby では refinements 内で mixin したメソッド内から同モジュールのメソッドを呼び出すことはできません。 module Homu def homu p "homu" end def mami homu end end module ObjectEx refine Object do include Homu end end using ObjectEx obj = …

【Ruby Advent Calendar 2015 1日目】C++er が Ruby を書いてみて驚いた10のこと

Ruby Advent Calendar 2015 とは Ruby について何か書くアドベントカレンダーになります。 現在は Qiita で開催しています。 Ruby Advent Calendar 2015 - Qiita まだ参加者は募集中なので気になる方はぜひ参加してみてください。 本題 さて、わたしは元々 C…

Ruby の #instance_eval と #instance_exec の違い

#instance_eval は渡されたブロックをレシーバのインスタンス元で実行するメソッドです。 なので例えば次のようにしてインスタンス変数をブロック内から参照する事ができます。 class X def initialize @name = "homu" end end x = X.new p x.instance_eval …

Ruby は #!= 内で #== が呼ばれる

#!= 内で #== が呼ばれているため、#== を再定義すると #!= にも影響が及びます。 [コード] class X def == other p "==" true end end X.new == "" # => true X.new != "" # => false [出力] "==" "==" #== に副作用があるとちょっと注意する必要があるかも…

Ruby でインスタンスオブジェクトに対して attr_accessor を使う

インスタンスオブジェクトに対して特異メソッドとして attr_accessor を使ってアクセッサを定義したかったので考えてみた。 class << を使って attr_accessor を呼び出すのがよいのかな? class X end x = X.new # インスタンスオブジェクトを渡す class << …

Ruby の using が refine 内だと反映されない

Refinements の refine 内では外のスコープで定義した using は反映されませんでした。 module A refine Object do def mami :mami end end end using A module B refine Class do def homu self.mami end end end using B Class.new.homu # => Error: undef…

Ruby の attr_accessor に対して外部のスコープの変数を渡したかった

どういうことかというと次のような事がやりたかった attr = :name class X # class 外の変数を attr_accessor に渡したい attr_accessor attr end [解決] 次のように Module + #include で解決することは出来ました。 attr = :name X = Class.new.include(Mo…

初心者 C++er Advent Calendar 2015 の募集を開始しました

なんとなく勢いで立てました。 初心者 C++er Advent Calendar 2015 - Adventar 初心者のためのゆるふわなアドベントカレンダーになります。 興味のある人は参加してみてくださいー。 ちなみにガチなネタを書きたい方は別のアドベントカレンダーもあるのでそ…

Qiita で Ruby Advent Calendar 2015 つくった

なかったのでつくった。 Ruby Advent Calendar 2015 - Qiita さすがに1人じゃ寂しいので気になる方は参加してみてください。