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

私の歴史と今

読んでて恥ずかしくなるのが私の歴史。だけどそのときは今現在のように真面目に書いていた訳でね。そんな私の今を書いていく。

RubyやRailsについて調べることが多かった

トランザクション中の例外について

トランザクションを使いたい時は、ActiveRecord::Base.transactionメソッドにブロックを渡せばいい訳だけど、その中で例外を発生させて、かつ、コミットしたい場合があった。

以下、イメージ。

ActiveRecord::Base.transaction do
  # 何かしらの処理
  if a_conditions1
    # 何かしらの処理
    record.save!
    if a_conditions2
      raise MyError.new
    end
  end
end

このままだと、save!後の例外発生でロールバックしてしまう。ロールバックされないように例外を発生させることはできないのか、と調べてみたが、結論、見つからなかった。

結局、以下のようにしたが、

ActiveRecord::Base.transaction do
  # 何かしらの処理
  if a_conditions1
    # 何かしらの処理
    record.save!
    if a_conditions2
      error = MyError.new
    end
  end
end
raise error if error.present? # トランザクションの外に出した。

以下のように例外をラップしてくれて、コミット後、ラップされた例外をraiseしてくれるようなもの(ActiveRecord::NoRollback)がフレームワークに用意されててもいいのになあと思う。

ActiveRecord::Base.transaction do
  # 何かしらの処理
  if a_conditions1
    # 何かしらの処理
    record.save!
    if a_conditions2
      raise ActiveRecord::NoRollback.new(MyError.new)
    end
  end
end

なお、transactionメソッド内のソースは以下となっている。

transactionメソッド

普通はelseが処理されてwithin_new_transactionメソッドが呼ばれる。rescueして亡き者にするのはActiveRecord::Rollbackのみ。

within_new_transactionメソッド

rescueされたら必ずロールバックされてしまう。ここでActiveRecord::NoRollbackの場合はロールバックしないようにしてくれたらいいのだけどなー。そんな単純な話ではないのだろうか。

Rubyのローカル変数が宣言されるタイミング

私はJavaから入ったのでいつも違和感がある。Rubyの場合はソースを上から解析していって、実行されなかったとしても変数宣言されているコードが存在していれば実際に宣言される。

if false
  a = 1
end
p a #=> 1

以下のようにしたくなる。

a = nil
if false
  a = 1
end
p a #=> 1

transactionメソッドに出てきた以下のようなコードも違和感。

begin
rescue Exception => error
ensure
  unless error
    #
  end
end

慣れだけの問題だけど。

Arelについて

そろそろ学んだ方がいいのかな、と調べたところ、

Arelでクエリを書くのはやめた方が良い5つの理由(Rails 5.0以前の場合)を読んで今はやめようと思いとどまった。

学ぶのはRails5.1がリリースされてからだ。

今日の所感

  • 久々にブログを書いたら、ちょっとした記事なのにめっちゃ時間かかる。
  • 従業員への要求が鏡のように自分に返ってきて勉強しなくっちゃという意欲(プレッシャー?)に変わる。
  • 久々に与沢翼の動画を見て少し感動した。彼のまっすぐなところは好きだ。
  • 去年から株と投資信託に手を出した。勧めてくる営業マンに好感を持ったからという理由だけで購入した。でも与沢翼の動画を見て、ちょっと調べてみることにした。
  • 従業員のソースレビューをした。2メソッドで1ページ半くらいのボリューム。動けばいい、というのは嫌なのできっちりレビューしたら、その修正に3時間以上かかった。必要以上な修正指示を出してしまったのかと今でも揺れている。コードが綺麗だからといってそれだけでお金を生む訳ではない。結局、動きさえすればお金を生んでくれる。修正に1時間程度かかるレベルのレビューだけをして、残りの2時間は新規のコード作りに費やした方がよかったのだろうか。

最後の投稿から1年が経とうとしている

最後の投稿が2016年12月28日なので、もうすぐ1年が経とうとしている。 あっという間だったなあ。

仕事

仕事はAndroidを自動化するアプリをRuby(Ruboto)で作成していたのでAndroidアプリそのものの知識が深まった。 最初はPC接続してPCから操作していたけど、最終的には自動化用のAndroidアプリを作ってAndroid端末単体で自動化できるようにした。 もちろんデータベースは外部にある。 自動化する内容はRubyで書く。

苦労したのは画像マッチングするために必要な画面キャプチャのパフォーマンス。 普通に取得すると数秒かかったりするので非常に苦労した。

あとはRubotoかな。 自動化する内容はRubyで書き、それをAndroid端末内で実行する訳だけど、クラスの再ロードに苦労した。 意外と難しいもので、ファイルは更新されているのに古いクラスが動いていたりしてデバッグに苦労したこともあった。

ゲーム

ゲームは白猫プロジェクトをやった。 子供が面白そうに遊んでいたのを見て興味が湧いて、親の方が好きになってしまった。 Youtubeに動画をアップして楽しんだ。

仏教

仏教も継続して学んだ。 学ぶほどその教えの深さに驚く。 因果、無常、罪悪、この3つだけを突き詰めていけば、人生において何をすべきなのかがわかる。 逆に言うと、私がこの私の人生において唯一求めていること(それは私が幸福になることであるがこれ以上に難しいことはない)を獲得できない方法もわかるということ。 仏教は学び続けていく。

何だか今年の総括になってきた。

Macbook

そういえば、Macbook pro retina 15 (2016)を購入したが、まだ届いていない。 初日にポチったが構成変更するために一度キャンセルして再購入したため、発表から1ヶ月経った今でも待ち状態。 来週くらいに届く予定なので楽しみにしている。 現在使用しているearly 2013は、デスクトップ移動すると画面がかくつくし8GBしかないのでメモリ不足になる。 それが改善されると思うとワクワクが止まない。

来年

今年は外部との接触をほとんど取ってこなかったので、来年は接触を持って行こうかと思っている。 あと、サラリーマンを辞めてから時間はあるのに逆に勉強をしなくなったので、目標を決めて勉強していく。

MySQLの「Sending data」はクライアントへのデータ転送ではない・・・

MySQLのshow processlistで「Sending data」と表示されている処理はデータ転送だと思っていたが、そうではなかった・・・。先入観って恐ろしい。

今日はサーバが重かったので調べてみたらすべてのコネクションが「Sending data」となっており、処理に3分以上かかっていた。slow queryのログを見ると「limit 1」の検索ばかり。転送なんてあっという間のはず。と思って調べてみたら「Sending data」はクライアントへのデータ転送ではなかった。

「This is quite a misleading status. It should be called "reading and filtering data".」

http://stackoverflow.com/questions/10347193/what-does-it-mean-when-mysql-is-in-the-state-sending-data

「データの読み込みとフィルタリング」ということだ。データを保存している場所を主語として「Sending data 」と表現しているのかな。わからないでもないけど、MySQLの処理なんだから誤解しやすい。