技術と関係ないことをまとめる場所
Carpは継承関係のモジュールを信頼する
初めに
以下のドキュメントにCarpの詳細説明があるので、それを読めば挙動が分かります。
Carp - モジュールのための warn と die の代替
この記事では、実際に継承してるコードを例に出して説明しようと思います。
コードと実行結果
client.pl
#!/usr/bin/env perl use strict; use warnings; use Concrete; Concrete->new->run(@ARGV);
Concrete.pm(具象クラス)
package Concrete; use strict; use warnings; use Carp; use parent 'Abstract'; sub speak { my $self = shift; croak "ダレカタスケテー"; } 1;
Abstract.pm(抽象クラス)
package Abstract; use strict; use warnings; sub new { my $class = shift; bless {}, $class; } sub run { my $self = shift; $self->speak; } sub speak {} 1;
実行結果
$ ./client.pl ダレカタスケテー at ./client.pl line 6.
挙動について
このコードを実装した際、呼び出し元がAbstract::runなので、
ダレカタスケテー at Abstract.pm line 12. と出るかと思ったら、
client.plの行数が出てしまいました。
これは何故かというと、継承関係にある呼び出し元は(具体的には@ISAに入っていれば)、
安全であると判断されスルーされます。
更に上位の呼び出し元はclient.plになるので、上記の実行結果となりました。
これだとエラーとしては分かり辛いなぁと思います。
対策
dieを使う
die
を実行した行数とそのファイル名を返します。
$ ./client.pl ダレカタスケテー at Concrete.pm line 10.
confessを使う
confess
はスタックトレースを伴うエラーを発生させます。
$ ./client.pl ダレカタスケテー at Concrete.pm line 10. Concrete::speak('Concrete=HASH(0x177b178)') called at Abstract.pm line 12 Abstract::run('Concrete=HASH(0x177b178)') called at ./client.pl line 6
Carp::verboseを有功にする
全てのcroak
をconfess
に、carp
をcluck
にとして扱うようにします。
CPANからダウンロードして使用している外部モジュールなども対象となります。
$ perl -MCarp=verbose client.pl ダレカタスケテー at Concrete.pm line 10. Concrete::speak('Concrete=HASH(0x184b1a8)') called at Abstract.pm line 12 Abstract::run('Concrete=HASH(0x184b1a8)') called at client.pl line 6
まとめ
Template Methodパターンで作ってたらこの問題にぶち当たりました。
CPANに公開しないモジュールであれば、confess
を使っておくのが良いかなぁと思ってます。
(die
は情報が少ないし、Carp::verboseはやりすぎ感がある……)
おまけ
evalで例外をキャッチするとこんな表示になります。
Abstract.pm(runを書き換え)
sub run { my $self = shift; eval { $self->speak }; if($@) { print "$@"; warn "チョットマッテテー"; } }
実行結果
Use of uninitialized value $_ in string at Abstract.pm line 14. ダレカタスケテー at Concrete.pm line 10. Concrete::speak('Concrete=HASH(0x1ec0178)') called at Abstract.pm line 12 eval {...} called at Abstract.pm line 12 Abstract::run('Concrete=HASH(0x1ec0178)') called at ./client.pl line 6 チョットマッテテー at Abstract.pm line 15.
eval {...} が追加されてますね!
やりたかっただけです!
Perl 5.8.8でfatpacked cartonを頑張って作った
carton bundle
を実行すると、App::FatPackerを用いて、cartonを1ファイルのスクリプトにまとめてくれます。
このfatpacked cartonをCentOS5のsystem perl(5.8.8)で使用したかったのですが、carton bundle
で生成されたfatpacked cartonを実行すると、エラーが発生して動きませんでした。
何とか動作させる方法を調べたので、エラーの原因と解消方法をまとめておこうと思います。
なお、carton bundle
でのfatpacked carton生成は、"experimental feature"のようです。
https://github.com/miyagawa/carton/issues/141
また、fatpacked cartonが原因の課題が多いため、carton bundle
ではデフォルトで作成させず、別コマンドに切り離すIssueが作成されてます。
https://github.com/miyagawa/carton/issues/156
Cartonのバージョン
v1.0.12
App::FatPackerがfatpackする条件
CHECKブロックで%INCからfatpackするモジュール一覧を取り出すので、それまでにrequireされたモジュール(のはず)
エラー内容と解決方法
1. Can't locate Algorithm/C3.pm in @INC
Algorithm::C3がfatpackされていないという理由で怒られます。
この問題の原因はClass::C3です。
CartonとAlgrorithm::C3の関係は以下の通り。
Carton \- Moo \- MRO::Compat \- Class::C3 \- Algorithm::C3
Class::C3はClass::C3::XSが存在する場合は、Algorithm::C3がrequireされません。
Class::C3::XSはPerlのバージョンが5.9.5より下であれば自動でインストールされるので、fatpackする時にXSが対象となり、Algorithm::C3はfatpackされません。
しかし、fatpacked cartonではXSモジュールのロードに失敗するので、Algrorithm::C3をrequireしようとしてエラーとなります。
(詳細はClass::C3のBEGINブロック参照)
対処法は、Class::C3::XSをuninstallすることです。
cpanm -U Class::C3::XS carton bunlde
因みに、Perl 5.10.0以上だとMRO::Compatのかわりにmroが使用されるので、この問題は発生しません。
(詳細はMoo/_mro.pmを参照)
2. List::Util version 1.33 required--this is only version 1.18
List::Utilのバージョンが古いという理由で怒られます。
これは、CPAN::Metaの2.133380以降がList::Utilの1.33以上に依存していることが原因です。
CartonはCPAN::Metaの2.120921に依存していますが、Perl 5.8.8のコアモジュールにCPAN::Metaが入っていないため、CPANからインストールされます。
この時インストールされるバージョンは2.140640(2014/03/11時点)です。
このバージョンではList::Util 1.33以上に依存しているので、併せてList::Util 1.38(2014/03/11時点)がインストールされ、carton bundle
時にfatpackされます。
しかし、List::UtilはXSモジュールなので、fatpacked cartonではロードに失敗します。
なので、コアのList::Utilが使われるのですが、バージョンが1.18と古いため、エラーが発生します。
対処法は、CPAN::MetaをuninstallしてCPAN::Metaの2.120921を入れ直せば良いです。
cpanm -U CPAN::Meta cpanm CPAN:Meta@2.120921 carton bundle
因みに、Perl 5.17.1以上だとコアモジュールにCPAN::Metaの2.120921が入っているので、この問題は発生しません。
まとめ
以下のどれかを採用しましょう。
- End of lifeとなったPerl 5.8.8とか使ってないで、Perl 5.18.2(or later)を使おう
- サーバセットアップ時にPerlと一緒にCartonをインストールしよう
- cpan-module-bootstrapを使おう
どうしてもPerl 5.8.8でfatpacked cartonを作りたければ、上記の方法で頑張ってつくろう。
AsakusaSatelliteを導入した
先月からAsakusaSatelliteというチャットアプリケーションを使い始めた。
今のところ、とてもいい感じに運用出来ているので、色々とまとめ。
なぜ導入したか
社内のコミュニケーションはHipChatを用いて行っているが、
業務を行っている場所では深遠な理由でホスティングサービスの利用許可が下りない為、
渋々IPMsg的なツールを使用していた。
しかし、チームメンバーが増えるにつれ、無視出来ない色々な問題が出てきた。
- オフライン時のメッセージが読めない
- 過去の発言を検索出来ない
- 送信失敗することが偶にある
- JenkinsやIssue Trackerの通知を流せない
不満が溜まりすぎて死にそうだったので色々探したところ、
AsakusaSatelliteがとても良さそうだったので導入してみた。
導入
AsakusaSatelliteはRuby on Rails製アプリで、DBはMongoDB。
主な特徴などは公式サイトにまとまっているのでそちらを参照のこと。
インストールはマニュアル通りにやれば特に問題は起きなかった。
プラグイン
プラグインによる拡張が可能で、デフォルトでも色々な拡張プラグインが入っている。
以下は使用している主なプラグインたち。
as_emoji_filter(絵文字)
GitHubでも使用出来る絵文字。
絵文字が使えるだけで結構バカに出来ない程の効果があって、
コミュニケーションを円滑にしてくれたり、発言しやすい雰囲気を作ることが出来る。
そういった空気を作ることで、情報の共有や議論が活発になるので大変重要。
今のところ一番人気の絵文字は:ok_woman:
as_chrome_notifier(デスクトップ通知)
自動テストのFailなどを素早くキャッチ出来るし、
他の人の質問などをスルーする心配も減る。
ただ、全部通知来ちゃうので、@allとか@userの時だけ通知が来るようにしたい。
as_localauth_plugin(ローカル認証)
Twitter認証だけだと不味いなーと思ってたらこんな便利プラグインが。
こういうプラグインがデフォで組み込まれてるのは本当に助かる。
as_auto_link(汎用リンク)
http(s)から始まるURLをリンクに変換したり、URL先の画像を展開したり。
tiqavとかミサワのURL貼って遊んだりする。
Jenkins AsakusaSatelliteプラグイン
こちらはJenkins側にインストールするプラグイン。
欲しいなーと思ったら用意されててビックリする。
使用感
今は10人位で使用しているが、急に異常終了したりとかは無いので安定してるなーという印象。
プラグイン拡張機能が素晴らしくて、自分のようなRuby初心者でも、GitLabのIssue/Merge Requestリンクフィルターとかすんなり作れた。
Jenkinsの結果を見に行くという苦行が無くなったので、それだけでもイノベーティブ。
GitLabのIssueやMerge requestのOPEN/CLOSE/MERGEも通知させていて、
Issueを作ったのになかなか気付いてくれない……みたいなことも減った。
Push通知はチャットが流れすぎるので非通知。
全文検索機能はレスポンスが結構早くてビックリした。嬉しい限り。
後は、AAが崩れないのを発見して、早速コピペして遊んでる。
改善したいところ
- Perlのシンタックスハイライトに対応していない
- coderayという外部モジュールが対応していない模様
- 最近GitLabが使い始めたHighlight.jsとかにすればいけるのかな
- RoomのPrivate/Publicを切り替えたい
- メイン部屋をPublicで作っちゃってどうしよう
- Roomタブが欲しい
- HipChatみたいに1画面で複数Roomみたい
まとめ
そんなこんなで、活用させて頂いてます。
開発者の方々、ありがとうございます。
GitLabのタイムゾーンをTokyoにする
環境
GitLab 6.4.3
タイムゾーンの初期値
GitLabは、Railsのタイムゾーンの初期値であるUTCとなっている。
OSのタイムゾーンを使用してくれないので、設定ファイルを修正する必要がある。
タイムゾーンの変更
config/application.rbを編集
cd /home/git/gitlab vim config/application.rb
タイムゾーンの設定を追記 (コメントアウトされてるので、その部分を編集)
config.time_zone = 'Tokyo'
GitLabを再起動
sudo service gitlab stop sudo service gitlab start
2013年振り返り
2013年をまとめ。
Perl
Perlを本格的に学び始めた。
はじめてのPerlを読みながら例題を解いて基礎を学び、一枚岩のスクリプトをガリガリとコーディング。
DBI使ってDBと連携、packageの作成、blessを使ったOOP、OrePANを使ったCPANのローカルミラー作成などもやった。
年末には、WAFについての知識を得る為、Plackハンドブックを読んだり、Amon2のソースを見たりしてた。
Perlを使ってると正規表現を駆使するので、自然と身について良かった。
2014年はCartonを使ったり、Amon2を使ってWebアプリケーションを作成したい。
Git
Gitを使ったことないことに危機感を覚えたので、新規プロジェクトでのソースコード管理をSubversionからGitに変更。
Pull Requestを使用したコードレビューも行いたかったので、GitLabも導入した。(GitHubは諸事情で不可)
ブランチの運用方法は、A successful Git branching modelを自プロジェクト用に変更した形態をとった。
Gitについてはメンバーが誰も使用したことがなかったので、調査や環境構築をしていた自分がアドバイザー役となった結果、今ではGitで戸惑うことは少なくなった。人に教えるって大事。
GitLab
昨年12月にGitLab 4.0をインストール。月一のアップデートは必ず対応し、現在動作しているバージョンはGitLab 6.4。
ユーザーは10人前後と少なめなせいか、特に大きな障害には見舞われず。
CentOS5系で運用しているので、アップデート時に色々問題が起きたりしてつらまったこともあった。(ブログネタが増えた―とも思ったけどw)
個人的にはIssueやMerge Requestがリナンバリングされるアップデートがきつかった。あれは無いわ―。
まぁ、今の所はそこまで不満はない。
その他技術系
- Jenkins
- CI環境を作りたかったので導入
- 個人的には多機能すぎると感じてるので、もっと軽量なCIツールに変えようかなーと考え中
- Docker
- CentOS 6.5で使えるようになったので軽く試した
- CIツールと組み合わせて色々出来そうな予感
- HipChat
- 社内のコミュニケーションツールとして導入
- 以前まで使っていたメールと比べると、遥かにコミュニケーションコストが低くて良い
カンファレンス
今年はPerlCasual #05とYAPC::Asia Tokyo 2013に参加。
新しい発見もあるし、いい感じに危機感も煽られるので、これからも定期的に参加しておきたい。
他の参加者とのコミュニケーションが不足してたので、積極的に交流しないとなー。
Blog
2013年は8記事を投稿。少ない。
他に有用な記事があると、書かなくてもいいか~となってしまいがち。
自分の考えを残しておくという意味でも、ちゃんと書き残しておきたい。
書籍
技術書6冊、技術雑誌17冊、ラノベ6冊、合計29冊。
ちょっと技術書が少ないなぁと反省。
来年は月3冊、年36冊くらいを目標にする。
プライベート
- 昨年9月に父親となったので、自由に使える時間が大幅に減少した
- でも子供の成長を見るのは楽しい
- あれだけ時間を費やしてたbeatmania IIDXをほぼやらなくなった
- 新曲をたしなむ程度に続けるつもり
- 隙間時間にできるiOSアプリをやるようになったけど、どれも飽きた
- LINE POP
- アルパカにいさん
- ラブライブ!スクールアイドルフェスティバル
- CROSS×BEATS
- Cookie Clickerはもっと早く飽きた
- あの盛り上がりは何だったのか
- 子供が保育園に行き始めてから、体調を崩すことが多くなった
- 自分の体の貧弱さに辟易
2014年の目標
現時点でやりたいなぁと思っていることを箇条書き。
ただ、方向転換が必要なら柔軟に対応するというスタンスなので、年始と年末でどれくらい考え方が変わっているか、というのも楽しみ。
- Javascriptを勉強する
- OSSに貢献
- 英語力の向上
- Blogを定期的に書く
- 体重+5kg
- Pocketの後で読む記事数が30以下
- 書籍の読了数36冊
GitLab 6.4にアップデートする際、libv8のインストールに失敗する
環境
CentOS 5.6(32bit)
GitLab 6.3(アップデート前)
問題
GitLabを手順に従って6.4にアップデートすると、 bundle install時にlibv8のインストールエラーが発生する。
エラー内容
Installing libv8 (3.16.14.3) Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension. /usr/local/bin/ruby extconf.rb creating Makefile Compiling v8 for ia32 Using python 2.4.3 Unable to find a compiler officially supported by v8. It is recommended to use GCC v4.4 or higher Using compiler: g++ Unable to find a compiler officially supported by v8. It is recommended to use GCC v4.4 or higher Traceback (most recent call last): File "build/gyp/gyp", line 15, in ? import gyp File "build/gyp/pylib/gyp/__init__.py", line 8, in ? import gyp.input File "build/gyp/pylib/gyp/input.py", line 14, in ? import gyp.common File "build/gyp/pylib/gyp/common.py", line 395 with open(source_path) as source_file: ^ SyntaxError: invalid syntax gmake: *** [out/Makefile.ia32] エラー 1 /home/git/gitlab/vendor/bundle/ruby/1.9.1/gems/libv8-3.16.14.3/ext/libv8/location.rb:36:in `block in verify_installation!': libv8 did not install properly, expected binary v8 archive '/home/git/gitlab/vendor/bundle/ruby/1.9.1/gems/libv8-3.16.14.3/vendor/v8/out/ia32.release/obj.target/tools/gyp/libv8_base.a'to exist, but it was not found (Libv8::Location::Vendor::ArchiveNotFound) from /home/git/gitlab/vendor/bundle/ruby/1.9.1/gems/libv8-3.16.14.3/ext/libv8/location.rb:35:in `each' from /home/git/gitlab/vendor/bundle/ruby/1.9.1/gems/libv8-3.16.14.3/ext/libv8/location.rb:35:in `verify_installation!' from /home/git/gitlab/vendor/bundle/ruby/1.9.1/gems/libv8-3.16.14.3/ext/libv8/location.rb:26:in `install!' from extconf.rb:7:in `<main>' GYP_GENERATORS=make \ build/gyp/gyp --generator-output="out" build/all.gyp \ -Ibuild/standalone.gypi --depth=. \ -Dv8_target_arch=ia32 \ -S.ia32 -Dv8_enable_backtrace=1 -Dv8_can_use_vfp2_instructions=true -Darm_fpu=vfpv2 -Dv8_can_use_vfp3_instructions=true -Darm_fpu=vfpv3 Gem files will remain installed in /home/git/gitlab/vendor/bundle/ruby/1.9.1/gems/libv8-3.16.14.3 for inspection. Results logged to /home/git/gitlab/vendor/bundle/ruby/1.9.1/gems/libv8-3.16.14.3/ext/libv8/gem_make.out An error occurred while installing libv8 (3.16.14.3), and Bundler cannot continue. Make sure that `gem install libv8 -v '3.16.14.3'` succeeds before bundling.
原因
libv8をインストールする場合、通常はバイナリ版を対象とするが、バイナリ版は64bit版しか用意されていない。
なので、ソースコードからのコンパイルとなるが、CentOS 5.8にデフォルトでインストールされているgccとpythonのバージョンが古い為、コンパイルエラーとなってしまう。
必要となるgccとpythonのバージョン
対応手順
gcc 4.4のインストール
sudo yum install gcc44-c++
pyhon 2.6のインストール(epelリポジトリが必要)
sudo yum install python26
このままだとデフォルトで入っているpython 2.4が使われてしまうので、gitユーザーだけ2.6が使われるように設定
mkdir ~/bin ln -s /usr/bin/python2.6 ~/bin/python echo 'export PATH=~/bin:$PATH' >> ~/.bashrc
再度 bundle install
cd ~/gitlab # MySQL sudo -u git -H bundle install --without development test postgres --deployment # PostgreSQL sudo -u git -H bundle install --without development test mysql --deployment
後は公式アップデート手順の通りに実行でOK
その他
上記手順でpython2.6へのリンクを削除していないが、GitLabが使用しているlibv8のバージョンが上がったら問題が再発するので、残していたほうが良さげ。