すがブロ

sugamasaoのhatenablogだよ

SimpleMagick v1.1.0をリリースした

オプションの使い方を(内部的に)変更した

いままで、明示的にresizeやquality等いくつかのメソッドを実装し、他は足りなければ additional_option で直接呼んでねっていうつもりで書いてたんだけど、それはあんまりだろうってことでmethod_missing使ってImageMagickで定義されてるオプションだったらそのオプション名を使うことにした。

一番でかい変更はImageMagickのオプションを定義するの毎回コピペするのだるいのでRakeタスクにして、Rubyのファイル自体作っちゃってる所ですね。使う分には互換性は保てているハズ。たぶん。

ところで今日は3/11ですね

3/11といえば、今年からはWebアプリエンジニア養成読本の発売日という意味が含まれるようになりました。よろしくお願いいたします。

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Ruby編、PHP編で書かれているサンプルソースGitHub上で公開されていますので、学びがありそうでしたら本書を手にとっていただけると嬉しいです。

ImageMagickをラップするSimpleMagickっていう薄いライブラリを作った

なぜか

MiniMagickが遅すぎたのだった。 MiniMagickはナウなヤングが使うイケテルツールとのことだったのだけど、コマンドにオプションを渡す度に mogrify コマンドを実行するため、でかい画像であればあるほど、前処理の為に時間が掛かる。まー初回にresizeを噛ませばちょっとはましになるところだけど、それにしても毎回実行してほしくない感じなのだった。

で、作ったのがこれ

使い方はREADMEにある通りだけど、こんな感じ。

require 'simple_magick'

if SimpleMagick.imagemagick_installed?
  image = SimpleMagick::Image.new('/path/to/src_image.jpg')
  image.resize '150x150'
  image.convert! '/path/to/dest_image.jpg'
end

実行するには ImageMagick 自体がインストールしてある必要がある(mogrifyを直接実行しているため)。

ベンチマークを取ると、ひとまずMiniMagickよりは早いことがわかる(これもREADMEに書いてある)。サンプルで使う画像次第で、如実に結果は変わるんだけど、自分が必要に迫られている現実ではもっと大きな差が出た(というか、ちょっと実用に耐えられなかったので自分で作ったのだけど)。

% bundle exec ruby benchmark.rb
                      user     system      total        real
simple_magick     0.080000   0.270000  28.530000 ( 29.687068)
mini_magick       0.410000   0.790000  31.300000 ( 37.115507)
ImageMagick       0.030000   0.170000  28.620000 ( 29.094316)

どうしても書かなくてはいけない宣伝

ぼくも一部執筆をした書籍が発売されます!!ジュンク堂等で先行発売しているところもあるようですが、3/11が正式な発売日です。

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

内容に関しては、献本しがいのある素晴らしい感想が書かれているエントリを見て頂ければ良いかなと思います。

出版記念イベントがあります!!!

電話で予約するという高難度イベントですが、まだ席に空きはあるそうなので、もしお時間があればぜひ。 - https://www.junkudo.co.jp/mj/store/event_detail.php?fair_id=4314

毎年忘年会に参加し続けた結果www

執筆する機会を得ることができまして、「Webアプリエンジニア養成読本」という本が近日発売する運びとなりました(ごめんね、ごめんね、タイトルは釣りです……)。

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)

著者紹介の文章、テンションおかしくて胸が熱くなります。

この本ってどんな本なの

今までWebアプリを書いたことがない人向けです。例えば、学校でプログラミング言語自体はならったけどWebアプリ作ったことないわーみたいな人とか。

正直な所、この本をもってプログラミング言語が理解できるような深い内容ではないです。まずは写経して、「なるほど、わからん」という部分はその他の入門書やWebサイトなどで補完してもらうという形です。

その代わり、HTTPの通信の仕組みやサーバーを構築するための基礎知識や運用監視についてまで、抑えておくと良い点が揃っていると思います。ようするに、Webアプリを作りたい!!だがどうすれば?という時に、この本に書かれている要素を頼りにしてより深く調べて行ってもらえると良いのかなと思います。

また、本の出版イベントも行う予定ですので、もし興味のある方はいらしてください。

三行で執筆経緯を

  • ハチイチ忘年会に毎年参加してたら仲の良い人ができた
  • 毎年朝までいるもんで幹事をやることに
  • そんなこんなでゆーすけべーさんからお声がけ頂くことに

所感

履歴を見ると、11/14に声を掛けてもらって、その後編集者さんと顔合わせや構成についての意識合わせをしたのが11月末くらいです。なので、2〜3ヶ月で執筆や校正をした感じですね。 こういうスプリント戦は(書くのが決まれば)楽で良いです……*1

執筆陣のスピード感が非常に良く、レスポンスの良さだったり締め切りにきちんと合わせてくるであったり、なんというか息のあった良いチームでした。

Webアプリを作ろうという2章の構成ではPHP編とRuby*2という別の言語それぞれ同じような題材を扱うという話なんですけど、PHP編を書いてる @uzulla さんが超絶文章書きまくってて*3本当にスゴいと思いました。スゴいんですよ。いやースゴい。

合わせて読みたい:『Webアプリエンジニア養成読本』を共著で執筆しました+イベントやります!

*1:パーフェクトRubyは2年近くかかったので

*2:あとPerlもちょっとある

*3:予定の分量の3倍とか

ささたつ会議(あるいは新年会)に行ってきました

去る1/26、ささたつ会議が行われました。

f:id:seiunsky:20140126174223j:plain

ノリで参加したのですが、ワイワイしながら料理を作るというリア充臭あふれるイベントでした。

記憶に残っているメモ

  • 2kgあった鶏肉が一瞬で無くなった
  • 酒もドンドンなくなっていく
  • すぎゃーんさんの将来が心配です
    • 一流の人間は何をやっても*1一流になるのがわかったし心配いらないよ
  • 料理も酒もうまくてヤバい感じだった
    • 料金も2000円くらい?でコスパ厨歓喜
  • というか手作り料理って滅多に食べないので感動もひとしおでしたね

f:id:seiunsky:20140126202135j:plain

写真で振り返るささたつ会議

写真NGの人もいるかもしれないので、とりあえず大丈夫そうな人だけ写ってるヤツを乗っけてみます。

これはしめ鯖という食べ物で、とてもおいしい

f:id:seiunsky:20140126182412j:plain

これは福井県民が涙を流しながら食べるという逸話のあるおあげ。おいしい

f:id:seiunsky:20140126184324j:plain

「たーっちゃん」って呼ばれて照れてる世界一の幸せ者

f:id:seiunsky:20140126191223j:plain

いわゆる唐揚げと呼ばれる食べ物なのですが、皿がテーブルに置かれた瞬間に食べられしまう

f:id:seiunsky:20140126203231j:plain

ラーメン屋のポーズ

f:id:seiunsky:20140126203056j:plain

どあきちゃん(CV: @do_aki)

f:id:seiunsky:20140126205759j:plain

イケメンはネギを持ってもイケメンであると暗に自慢している図

f:id:seiunsky:20140126215219j:plain

ちなみに、世界一の幸せ者タスキは @kamipo に継承されました

唐揚げの作り方を学ぶことは出来ませんでしたが、とても楽しかったですし、料理も美味しかったです。料理を作ってくれた方、お酒を持ってきてくれた方、企画・実行をしてくれたささたつさん、ありがとうございます!!1

関連リンク:ささたつ会議(新年会?) - Togetterまとめ

*1:ドルヲタでも

2013年をまとめる

まとめようと思ったのですが

ブログを読み返してこの一年を振り返ろうと思いましたが、ぜんぜん書いてなくて何も振り返られないですね。最悪です。

なんとなくがんばってまとめると

今年の抱負

  • ブログをもうちょっと書こう
    • というか新しいテクノロジーとか触った時にきちんと所感を書くというのをしたほうが良い……
    • 深刻な語彙力低下をなんとかするためにも
  • コードももっと書いていかないと
    • すぎゃーんの彼女作ってる場合じゃない!!!1
  • 今年もどこかでトークできるように精進していきます

パーフェクトRubyから泣く泣く削った標準添付ライブラリ パーフェクトRuby Advent Calendar 2013(12日目)

なんとなく12日が空いていたので書いてみます*1

このエントリは パーフェクトRuby Advent Calendar の12日目のエントリです。 前の日のエントリはイオリさん http://iori-o.github.io/blog/2013/12/11/perfect-ruby-2013-12-11/ でした。

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRubyから泣く泣く削った標準添付ライブラリ

ページ数の都合で泣く泣く削ることになってしまった部分というのが多少なりともあります。その他にこれも載せたほうが良いんだけどページ数が(ryというのもあります。

そこで削ってしまったけど、本当はあると良かったなというのを紹介します。

IO#select

これはいわゆるselect(2)を提供してくれます。select(2)って何スカっていうとman select 2すれば良いじゃないって感じなんですけど、たぶんIOオブジェクト(もっと言うとファイルディスクリプタかな)を待ち受けて、読み取り準備ができたオブジェクトを返すって感じですかね。

で?っていう

例えば、TCPServerのサンプルとかで使われてるので、こういう事例を見ると良いと思う。

ここのサンプルソースでTCPServerを使ったエコーサーバがある。

require "socket"

gs = TCPServer.open(0)
socks = [gs]
addr = gs.addr
addr.shift
printf("server is on %s\n", addr.join(":"))

while true
  nsock = select(socks)
  next if nsock == nil
  for s in nsock[0]
    if s == gs
      socks.push(s.accept)
      print(s, " is accepted\n")
    else
      if s.eof?
        print(s, " is gone\n")
        s.close
        socks.delete(s)
      else
        str = s.gets
        s.write(str)
      end
    end
  end
end

これの nsock = select(socks) ってところで使われている。実はKernel#selectはIO#selectと同じなので、単にselectとも書けるのだった。

ここでやってるのはTCPServerをopenして開いたsocketをIO#selectで待って、入力があったらその文字列をそのまま返却する(s.write(str)のところ)というのをやってるわけですね。

ちなみに、上記のスクリプトを実行するとこんな感じで出力がある。

% ruby sample.rb
server is on 51450:0.0.0.0:0.0.0.0

そうしたら、別のターミナルからおもむろに telnet localhost 51450*2 して、何か文字列を打ってみると動作を確認できます。

このIO#selectというのは配列の配列で返ってくるのでなかなかデータ構造を把握するのが大変なのですが、こういう低レイヤーっぽいものの動作を調べるのもなかなか楽しいですよね。

次のアドベンターは id:akiinyo さんです。本書のレビューでも助けて頂きました……!!

*1:11日を書いたイオリさんに指名も受けてしまいましたし

*2:ポート番号は実行のたびに変わる

パーフェクトRuby Advent Calendar 2013(5日目)

なんとなく5日が空いていたので書いてみます。

このエントリは パーフェクトRuby Advent Calendar の5日目のエントリです。 前の日のエントリは http://d.hatena.ne.jp/zonu_exe/20131204/1386271407 でした*1

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRubyに載っていない便利クラス

パーフェクトRubyで組み込みクラスや標準添付ライブラリ等を説明しています。とはいえ、全てを網羅しているわけではありません。 そんな漏れているクラスのなかでもマル得情報として名高い(と勝手に思っている)クラスとしてTSortがあります。

このTSortは依存関係をイイカンジに解決してくれるトポロジカルソートっていうのを提供してくれる。

require 'tsort'

class Hash
  include TSort
  alias tsort_each_node each_key
  def tsort_each_child(node, &block)
    fetch(node).each(&block)
  end
end

{1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
#=> [3, 2, 1, 4]

依存という言葉を使っているけど、位置とか距離って言ったほうが正しい気もする。 tsortメソッド実行した結果を見るとわかるかもしれないけれど、3というのは1と2から参照されているので、先頭に並び替えられる。同じように、1は2と3を参照していうるので、2よりも後に来るという感じ。言葉で説明するのむずかしいですね。

実は

すごい知った風に紹介しましたけど、ainameさんのエントリ で知っただけでした。ぼくはそれまでこのクラスを知りませんでしたけど、なんとなく知っていると助かる可能性が微レ存な気がするので、使い方を覚えておいて損はしなそうだと思ってます。

次のアドベンターは

パーフェクトRuby執筆者でもある id:joker1007 さんです。どんなエントリになるのか、楽しみですね。

*1:12/4のエントリが書かれたようなので修正しました