トップ 追記 RSS feed

継続にっき

2004|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|12|
2006|01|03|05|06|08|09|10|12|
2007|01|02|03|05|07|12|
2008|10|
2009|01|05|12|
2010|04|05|11|
2011|01|09|12|
2012|02|03|05|09|12|
2013|02|03|
2014|05|09|

2014-09-20 (Sat)

))) RubyKaigi 2014 まとめ

「Power Assert in Ruby」というタイトルで発表してきました。まさかRubyKaigiの壇上に立つ日が来るとは。光栄な話です。

以下、振り返り。

  • RubyKaigi当日まで
    • CFPの締め切り1週間ぐらい前にpower_assertがtest-unitに組み込まれることになったので勢いでsubmitボタンを押す。
    • 準備しだすも誰得な話にしかならないような気がしてきて延々とスライドの構成に悩む。 *1
    • Rebuild.fmのa_matsudaさん回を聞いたことで、追い打ちのようにハードルが3段階ぐらい上がる。
  • 1日目
    • nagachikaさん、ささださん、nariさんと冒頭から連続3セッションで名前を出してもらったことで謎の達成感を得る。
    • Hall-Aが期待を裏切らない濃さで満足。
    • Ruby committers vs the Worldでマイクが回ってくる。パターンマッチ入れたいですよね。
  • 2日目
    • MatzのキーノートはRuby 3.0の話。あれ、パターンマッチは…?
    • Power Assert in Ruby
      • 会場の反応がよくてスピーカーとしては大変やりやすかったです。来ていただいた方、ありがとうございました。
      • 「TracePoint使っている人」と聞いて手が上がったのは10名強というところ。このセッションをきっかけに利用者が増えるとうれしいです。
      • akrさんのメソッド再定義すればいいんじゃないかという指摘は目から鱗だった。なるほどなあ。
        • アトミックに出来るかどうかがまずはポイントかな。
        • 影響範囲を限定するためにRefinementsと組み合わせるということを考えてみたけどこれは微妙?
      • コアに欲しい機能は、ということでいくつか。
        • TracePoint経由で位置情報を取得。
        • method_missingが呼ばれたときにオリジナルのメソッドのidを取得する手段。
        • JavaScriptのarguments相当。
          • これがあると差分比較まで行える。
        • Procのソースコードを取得する手段。
          • PowerPをgemにしていないのはこれが理由で、ruby -e 'p { foo }'などとされると対応しようがない。
    • 夜は#unagiawardへ。yharaさん曰く「神々の集い」。鰻が運ばれてくるまでの間に2.0.0-p576/2.1.3がリリースされている辺りさすがというほかない。
    • #unagiaward解散後にMatz達と合流することになったものの風邪気味だった体調が悪化してきたので退散。その後も面白い話があったようで残念すぎる。
  • 3日目
    • 午後からふらーっと行ってコードを書いたり。

最後に。今回、スピーカーということでスタッフの方の活動を目にする機会が多かったのですが精力的な仕事ぶりに圧倒されました。スタッフの皆さん、本当にありがとうございました。

*1 悩むだけ悩んで結局当初の構成ほぼそのままだったんですが、それなりに好評だったようで安心しました。


2014-05-31 (Sat)

))) test-unit-power_assertをリリース

Groovyなどいくつかの言語のテストフレームワークには、テスト失敗時にコードの各式の値を出力するPower Assertと呼ばれる機能があります。 今回、Ruby 2.0以上 + test-unit向けに同様のものを実装してみました(test-unit-power_assert)。

利用例は以下の通り。

require 'test/unit'
require 'test/unit/power_assert'
class MyTest < Test::Unit::TestCase
  def test_failed
    power_assert do
      "0".class == "3".to_i.times.map {|i| i + 1 }.class
    end
  end
end

power_assertメソッドにテスト対象の式をブロックとして与えるだけですが、出来れば-rオプションを使うなどしてテストコードが読み込まれる前にこのライブラリをrequireするようにしておくと情報の取りこぼしを防げます。

# 事前requireなし

        "0".class == "3".to_i.times.map {|i| i + 1 }.class
            |            |    |     |                |
            |            |    |     |                Array
            |            |    |     [1, 2, 3]
            |            |    #<Enumerator: 3:times>
            |            3
            String

# 事前requireあり

        "0".class == "3".to_i.times.map {|i| i + 1 }.class
            |     |      |    |     |                |
            |     |      |    |     |                Array
            |     |      |    |     [1, 2, 3]
            |     |      |    #<Enumerator: 3:times>
            |     |      3
            |     false
            String

追記(2014/08/04)

test-unitにPower Assertが標準機能として取り込まれassertメソッドにブロックを渡せるようになりました ([ruby-list:49902] [ANN] test-unit 3.0.0)。 これを受けてtest-unit-power_assertもバージョンアップを行い、同様の書き方ができるようにしています。


2013-03-23 (Sat)

))) MathematicaっぽいパターンマッチをRubyで実装する

ScalaっぽいパターンマッチをRubyで実装するから始まった 一連のpattern-matchライブラリ関連エントリのおそらく最終章。 任意のオブジェクトに対して正規表現相当のマッチをできるようにしてみたのでその紹介です。

どういうことかと言うと、例えば配列をFixnumの前後で分割したりとか

match([:a, 0, :b, :c]) do
  with(_[*a, Fixnum, *b]) do
    a #=> [:a]
    b #=> [:b, :c]
  end
end

連続した要素の積が12になるところを探したりとか

match([1, 2, 3, 4, 5]) do
  with(_[*_, *a, *_], guard { a.inject(:*) == 12 }) do
    a #=> [3, 4]
  end
end

「シーケンス中で連続して同じ値が入っている各箇所について,2 個目以降は削除したシーケンス」を取得したり (前後の値も利用したシーケンス処理 - NyaRuRuが地球にいたころ)とか

def replace_repeated(obj, &block)
  ret = match(obj, &block)
  if ret == obj
    ret
  else
    replace_repeated(ret, &block)
  end
rescue PatternMatch::NoMatchingPatternError
  obj
end

replace_repeated([1, 2, 4, 4, 3, 3, 4, 0, 0]) do
  with(_[*a, x, x, *b]) { [*a, x, *b] }
end #=> [1, 2, 4, 3, 4, 0]

こういった処理が簡単に書けるようになりました。

先日のRuby開発者会議でパターンマッチを入れたいねみたいな話をしてきたのですが、 せっかくならこのぐらい出来るようになると楽しそうです。


2004|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|12|
2006|01|03|05|06|08|09|10|12|
2007|01|02|03|05|07|12|
2008|10|
2009|01|05|12|
2010|04|05|11|
2011|01|09|12|
2012|02|03|05|09|12|
2013|02|03|
2014|05|09|
トップ 追記 RSS feed