きりかノート 3冊め

おあそびプログラミング

rb22-*なportがぜんぜんない

とくに結論のないはなし。

MacPortsにrb22-てportないんだけど、なんか例とかないの?」てメールが来た。

PortGroup rubyの確認用に手元では作ってるので、そいつを簡略化してgistに上げて「これ見て」と返信しておいた。

ruby.setup

MacPortsにはPortGroup(コード)という仕組みがあって、Portfileを簡単に書けるようにいろいろサポートしてくれる。

自分が担当する前(ruby-1.8.6以前のころ)から、PortGroup rubyにはruby.setupキーワード(tcl的にはproc)があって、これを使うと簡単にRubyのライブラリやツールがインストールできるようになっている。

前述のgistの例でいうと、

   ruby.setup          bundler 1.10.1 gem {} rubygems ruby22

で、この行のruby22をruby21にすればport:ruby21用のPortfileになる。(実際にはPortfileのファイル名も変えないとlintにはひっかかる)

これはrubygemsを使う例だけど、他にもいろいろなインストール手法に対応していて、

  • setup.rb
  • extconf.rb && make && make install
  • install.rb (1) basic_install.rb - 実行するとぜんぶインストールする。
  • install.rb (2) - config.saveを生成するタイプ。
  • make (このタイプpdumpfsしか見たことない…)
  • 単純にコピー

などが利用できるようになっている。でもいまどきはgemしかないよね。

rb22-* なportはなぜないのか / そもそもいるの?

直接にはだれもコミットしてないからなわけだけど。いちお考えてみると、

  • brew使ってる
  • gem installすればいい

あたりだよねえ。きっと。

個人的にはgem install|updateすればいいし、portつくって更新に追従するのもめんどう、といったところ。

ただそれは自分がrubyユーザだからそう思うわけで、そうでない人が特定のコマンド使いたいだけで「gem installしてね」というのもどうなんじゃろ?とも思える。(冒頭の質問してきたひとはRailsやってるて書いてたのでgemやbundler使ったほうがよくね?と思うけれど)

たとえばackPerlsphinxblockdiagPythonなわけだけど、それぞれに応じてcpanやpip使いわけてね!ってのものなんだかびみょーな気持ちはぬぐえないよな。

cpan2portのように言語のパッケージシステムから自動でPortfile生成するのもあって、これのgem用のをつくるのもそんな難しくないけど、じゃあ欲しいかっていうとそうでもないよなあ。

第72回 Cocoa勉強会に行ってきた(5/23)

会場はいつもの新宿伊藤ビルの貸し会議室
ここのとこ休んでたのでわりとひさしぶり。

なんか今回は「Cocoa……?」な回でした。資料はconnpassのほうとか。

発表

業務システム開発の話。自分はそっち側の人間なわけだけど、わかることもそうでないことも。

RSpecに強く影響を受けたテスティングフレームワークQuickの話。ちょうどその後にネット上でまたRSpecについて盛り上がってたのでいいタイミング?

自分はずっとtest-unit派でRSpecよくわからんのだけど、せっかくの機会なので"Better Specs { rspec guidelines with ruby }"とか読んだりしてる。

普段使い+ラズパイ機器の開発にも使える持ち運び可能なディスプレイの話。あいかわらずハードウェアはさっぱりわからん。話聞いてるのは面白いのだけれど。

次回の予定

次回は7月の予定です。

MacPortsのport:ruby22, ruby21, ruby20を更新

あたらしいバージョンがリリースされていたので対応しました。

  • port:ruby22: 2.2.2
  • port:ruby21: 2.1.6
  • port:ruby20: 2.0.0-p645

2.2にはtk-8.6対応が入ったみたいなんだけど、手元での確認が終わらなかったのでtkバリアントはまだ有効にしていません。次までにはなんとかしたいかな。

あと2.2でサポートしたjemallocもバリアントに次から追加する予定(手元ではテスト済み)です。gmpと同様に、デフォルトはオフで+jemallocで有効になるようにします。

MacPortsのport:ruby22, ruby20を更新

あたらしいバージョンがリリースされていたので対応しました。

  • port:ruby22: 2.2.1
  • port:ruby20: 2.0.0-p643

2.0.0は最後の通常リリースです。2.2.1はたぶん通常の定期リリースだと思います。

また、1.9.3系は先月でサポート終了しました。今までありがとう!

MacPortsのport:ruby21, ruby20, ruby19を更新(セキュリティ修正あり)

あたらしいバージョンがリリースされていたので対応しました。

  • port:ruby21: 2.1.5
  • port:ruby20: 2.0.0-p598
  • port:ruby19: 1.9.4-p551

今回もセキュリティ修正を含みます。詳細は公式の情報をごらんください。

先日あった、2.1系のコンパイルが古いOS Xでは止まってしまうことがある問題は修正され、2.1にもマージされました。Portfile側でconfigureのオプションを追加していたのを削除しています。

Yosemite用のRubyCocoa 1.2.0インストーラを公開

うん、すっかり忘れてた。Yosemite環境用のインストーラを用意しました。

ruby-1.8はOS X 10.10には入っていないので、ruby-2.0用のもののみです。1.8で使いたい人は先日の1.8用の一式を使ってください。

また、内容は7月にリリースした1.2.0のままなので、ruby-2.0関連の修正されていない不具合があります。trunkでも直ってないんだけど。

MacPortsのport:ruby21, ruby20, ruby19を更新(セキュリティ修正あり)

あたらしいバージョンがリリースされていたので対応しました。

  • port:ruby21: 2.1.4
  • port:ruby20: 2.0.0-p594
  • port:ruby19: 1.9.4-p550

今回のリリースはセキュリティ修正を含みます。詳細は公式の情報をごらんください。

また、今回のリリースからPOODLE対応として安全でないとわかっているSSL/TLSオプションが無効になっています。こちらも公式ページに説明があります。

MacPortsrubyとしては、この変更を取り消すvariantは用意しません。

OS X 10.7と10.8でコンパイルが終了しない対策

buildbotの進捗をながめてたら、10.7と10.8のビルドがタイムアウトで失敗していた。手元の10.7環境で試してみたところ、minirubyでrbconfig.rbを生成するところで止まってることが確認できた。どうもminirubyがおかしいみたい。`./miniruby sample/test.rb`を実行してみてもうんともすんとも言わない。

このレベルで動かないのはconfig.hがおかしいことが多いので、正常に動作した10.9環境と比べてみる。

   % diff -u config.h-10.9 .ext/include/x86_64-darwin11.0/ruby/config.h
   --- config.h-10.9	2014-10-28 02:38:10.000000000 +0900
   +++ .ext/include/x86_64-darwin11.0/ruby/config.h	2014-10-28 22:09:09.000000000 +0900
   @@ -272,7 +272,6 @@
    #define HAVE_UTIMES 1
    #define HAVE_WAIT4 1
    #define HAVE_WAITPID 1
   -#define HAVE_BUILTIN___BUILTIN_BSWAP16 1
    #define HAVE_BUILTIN___BUILTIN_BSWAP32 1
    #define HAVE_BUILTIN___BUILTIN_BSWAP64 1
    #define HAVE_BUILTIN___BUILTIN_CLZ 1
   @@ -316,9 +315,9 @@
    #define DLEXT_MAXLEN 7
    #define DLEXT ".bundle"
    #define LIBDIR_BASENAME "lib"
   -#define RUBY_SETJMP(env) _setjmp((env))
   -#define RUBY_LONGJMP(env,val) _longjmp((env),val)
   +#define RUBY_SETJMP(env) __builtin_setjmp((void **)(env))
   +#define RUBY_LONGJMP(env,val) __builtin_longjmp((void **)(env),val)
    #define RUBY_JMP_BUF jmp_buf
    #define HAVE_PTHREAD_H 1
   -#define RUBY_PLATFORM "x86_64-darwin13.0"
   +#define RUBY_PLATFORM "x86_64-darwin11.0"
    #endif /* INCLUDE_RUBY_CONFIG_H */

まー、RUBY_SETJMP()やRUBY_LONGJMP()あたりがあやしいよね。configureのオプションで--with-setjmp-type=_setjmpとして強制的に指定してやればminirubyは動くようになって解消した。とりあえず、MacPortsのPortfileにはこれを入れて対処することに。

抜本的な対応は、rubyのupstreamのほうでどうにかしよう。

(10/29 追記)trunkに修正が入り、この問題は解消しました。はやすぎる!

忘れがち、OS Xの標準のファイルシステムは大文字小文字を区別しない

ちょっと前にMacPortsのチケットで問い合わせがきてた(#45257 (ruby20: warnings from library files that differ only by case of filename) – MacPorts)ものについて、慣れてるとすぐあたりがつくんだけど、気付かないとだいぶイミフなのでメモ残しとこう。

これはMacPorts固有の現象でもないので、10.9 Mevericksに添付のrubyで試してみよう。

   % irb -w --simple-prompt
   >> RUBY_VERSION
   => "2.0.0"
   >> require 'Digest'
   => true
   >> Digest::MD5.digest("!")
   /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/digest.rb:4: warning: method redefined; discarding old const_missing
   /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/Digest.rb:4: warning: previous definition of const_missing was here
   /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/digest.rb:28: warning: method redefined; discarding old file
   /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/Digest.rb:28: warning: previous definition of file was here
     :

定数が上書きされてるよ!という警告がでてきてしまう。これはなぜ?という話。もちろん実際にはファイルは小文字の名前の"digest.rb"しかない。

requireされたファイルを見てみると、確かに"digest.rb"と"Digest.rb"のふたつの名前が読み込まれている。これは実際には同じファイルだ。

   >> $LOADED_FEATURES.grep(/digest/i)
   => ["/System/Library/.../lib/ruby/2.0.0/universal-darwin13/digest.bundle",
       "/System/Library/Frameworks/.../lib/ruby/2.0.0/Digest.rb", # *D*igest
       "/System/Library/Frameworks/.../lib/ruby/2.0.0/digest.rb", # *d*igest
       "/System/Library/.../lib/ruby/2.0.0/universal-darwin13/digest/md5.bundle"]

原因はOS Xの標準のファイルシステム、HFS+がファイル名の大文字小文字を区別しないことだ。

1. require "Digest" → $LOAD_PATHから"Digest.(rb|bundle)"を探すと(詳細はるりまのKernel#require参照)、ファイルシステムは大文字小文字を区別しないので「"Digest.rb"があるよ」と答える → digest.rbが読み込まれ、"Digest.rb"として$LOADED_FEATURESに記録される。
2. Digest::MD5したとき、const_missingの処理の中で`require "digest"`される。"digest.rb"はまだ$LOADED_FEATURESの中にはないので、同じ"digest.rb"が読み込まれる。

という流れみたい。今回は警告メッセージ出すようにしてたから気付けたけれど、ファイル名の大文字小文字がちがってても動いてしまうので、そのまま他の環境に持っていくと動かない。ということもあるので注意。

Mac用のアプリでもこのへんわりとぐだぐだで、ファイルシステムを大文字小文字区別するHFSXに変えると動かないものがあるというのは時々聞く話。でも個人的にはそろそろ標準をHFSXにしてほしいなあと思う。

RubyCocoa with Ruby-1.8 on Yosemite

ちょっとまだruby 2.0対応版に問題があるようなので、とりあえず用意しました。Yosemite GM3上で簡単に動作確認済みです。

配布物は次の2つです。

ruby-1.8.7-p374とRubyCocoaインストーラは別々です。rubyは--disable-sharedしてつくったので、組み込みライブラリとCocoaだけで構成されたアプリであれば、ruby本体は不要です。

標準添付ライブラリや他のgem・ライブラリを使用している場合(ようするにアプリのコード以外にrequireしている場合)は、アプリケーション単体で配布するにはRubyCocoa添付のstandaloneify.rbを利用して、アプリケーションバンドルに必要なファイルをアプリケーションに含める必要があります。

 % ruby standaloneify.rb -f -d YourApp.app /path/to/build-dir/YourApp.app

なにかあればお知らせください。