5/27(水)にNTT-ATさんの会議室にてkawasaki.rb #024を開催しました。

togetterのまとめはこちら

24回目ということで、なんとKawasaki.rbは今回で約2周年となりました。おめでとうございます!

パーフェクトRuby読書会

「3-6-4 割り込みハンドラを定義する」まで終えました。

3-6-3 外部ファイルを読み込む

Karnel.#requireは、既存ライブラリや別ファイルに用意したプログラムを読み込む際に使います。

1
2
require 'erb'
# => true

requireに指定できるファイルはRubyスクリプトか拡張ライブラリ(.so,.dll,.bundle)です。拡張子は省略できます。 引数に相対パスが指定された場合、$LOAD_PATH($:)に含まれるディレクトリを順番に探し、最初に見つかったファイルをロードします。

1
2
$LOAD_PATH
# => ["/usr/local/opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/coderay-1.1.0/lib", "/usr/local/opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/slop-3.6.0/lib", "/usr/local/opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/method_source-0.8.2/lib", ...

requireされたファイルのパスは$LOADED_FEATURES($”)に追加されます。 同じパスのファイルは一度しかロードされません。ただし、同じファイルをシンボリックリンク経由でrequireした場合、パスが違うため2回ロードされます。

1
2
$LOADED_FEATURES
# => ["enumerator.so", "rational.so", "complex.so", ...

Karnel.#require_relativeは、実行中のファイルからみた相対パスでrequireを行います。$LOAD_PATHは探索されません。

1
2
3
# 実行ファイルと同じディレクトリにmylib.rbが存在する場合
require_relative 'mylib'
# => true

Karnel.#loadはrequireと同じく外部ファイルを読み込みますが、拡張子の補完は行いません。また、requireと違い同じファイルパスを 何度でも読み込むことができるので、設定ファイルを読み込むことに多く用いられます。

1
2
3
4
5
6
7
8
require './mylib'
# => true
require './mylib'
# => false
load __dir__ + '/mylib.rb'
# => true
load __dir__ + '/mylib.rb'
# => true

$:や$LOAD_PATHには探索パスが配列で格納されており、パスを追加することで探索パスを追加することができます。

1
2
3
4
5
6
require 'mylib'
# => LoadError: cannot load such file -- mylib from /usr/local/opt/rbenv/versions/2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
$LOAD_PATH << File.dirname(__FILE__)
# => ["/usr/local/opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/coderay-1.1.0/lib", ... ,"."]
require 'mylib'
# => true

3-6-4 割り込みハンドラを定義する

Kernel.#trapを使用すると、割り込みのシグナルに対応するハンドラを登録することができます。 以下のプログラムを実行中に、SIGINTを送信するとメッセージを出力して終了します。

1
2
3
4
5
6
7
8
trap :INT do
  puts "\nInterrupted!"
  exit # exitを呼んでおかないとSIGINTで終了されなくなる
end

loop do
  sleep 1
end

また、trapは上書きすることができ、下記のプログラムの場合、SIGINT送信後に”Interrupted2”が表示されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
trap :INT do
  puts "\nInterrupted1"
  exit
end

trap :INT do
  puts "\nInterrupted2"
  exit
end

loop do
  sleep 1
end

そして、trapの戻り値は上書きする前のシグナルハンドラとなっているので、再定義の際に前のシグナルハンドラを保存することができます。 下記の例では、”Interrupted2”が表示された後、old_handler.callによって”Interrupted1”が表示されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
trap :INT do
  puts "\nInterrupted1"
  exit
end

old_handler = trap :INT do
  puts "\nInterrupted2"
  old_handler.call
  exit
end

loop do
  sleep 1
end

書籍「なるほどUnixプロセス - Rubyで学ぶUnixの基礎」では、これを利用した例としてgemのmemprofを紹介しています。 リンク

今回のiruby notebookは以下のとおりです。

別タブで開く

Kawasaki.rbで2年に渡って進めてきたパーフェクトRuby読書会ですが、今回で無事3章が終了し、次回は4章「クラスとモジュール」になります。

セッション

今回は発表者が多く、4名の方に発表していただきました。

Docker 基本のおさらい from @nk_ngzmさん

社内講習会で発表したDocker初学者向けの資料を一部抜粋し発表していただきました。Dockerについて懇切丁寧に解説されていて、翌日の はてブのテクノロジー欄でホットエントリー入りもされていました。拍手。

Unix プロセスと Docker の罠 from @kechakoさん

Dockerでゾンビプロセスが大量に発生したことを調査するため、「なるほどUnixプロセス」をもとにRubyのプロセスを調査し、さらにDocker上での 挙動をまとめた内容について発表されていました。

発表されたエントリーはこちら

Rubyistがgemの前にPypiデビューするのは間違っているだろうか from @chezouさん

Rubyistであり本勉強の発起人でありRubyKajaにも選ばれたchezouさんがgemよりも先にPypiデビューしたという話をされました。 今回作成したpipは形態素解析器であるKyTeaを、Pythonから扱えるようにしたMykytea-pythonで、 本発表ではpip化するにあたっての苦労した点などを話されていました。

React.jsでRailsのScaffoldを再現してみた from @Peranikov

以前にQiitaに投稿した、RailsのScaffoldで生成したようなアプリケーションをReact.jsを使って作成したという記事を紹介しました。

発表したエントリーはこちら

この記事は以前にすぎゃーんさんの記事で紹介され、そのことについても触れました。

申し訳ありませんでした。

次回予告

次回は6/24(水)開催の予定です。ご参加お待ちしております。

寄稿者について

松久保 敬人 (@Peranikov)

RailsからiOSから何でもやってる人。お酒を投稿するサイトPuhaar!を運営しています。

Published: May 30 2015

blog comments powered by Disqus