カテゴリー別アーカイブ: Ruby

Ruby 1.9.3インストール: yumリポジトリ追加時の依存性の欠如エラー – libyaml

ほったらかしにしていたとある自鯖のRedmineのアップグレードに際し、Ruby 1.9系のビルドに必要なlibyamlをyumでインストールする為にEPELリポジトリを追加しようとしたら下記のエラーが発生。尚、epel-releaseパッケージのURLは以下のページより確認。

http://dl.fedoraproject.org/pub/epel/6/x86_64/repoview/epel-release.html

よくよく確認したら対象OSバージョンがv5.9だった。。

v5.x系のパッケージをインストールするのも何だし、先ずはOSをv6.x系にUpgradeするかな。いや、v5.x系からv6.x系へのアップグレードはコマンドではなくOSの再インストール推奨されていることを考えると、一先ず、v5.x系でlibyamlをインストールする。

後はRuby v1.9.3のインストール作業となる。

JavaとRubyで文字列の終端の扱いの違い

RubyのコードをJavaに書き直す際に注意する相違点が幾つかあったので、そのうちの一つを挙げてみます。特に文字列関係は色々やりにくいです。

Rubyでは文字を[]で指すとき終端文字の次の添え字を指すとnilを返します。これをCで言う文字列の終端文字’\0’のように考え、if文などの判定に用いることが出来ます。

対して、Javaで同じような書式で書こうものなら、

のように例外でキャッチしなければなりません。

実行結果

まぁ、str.length()を用いて文字列長でcharAtで指す文字が文字列の末尾かどうかを判定することで制御すればよいまでの話かもしれません。

今回はとあるアルゴリズムを移植上、気づきが色々あったのでこうした機会に言語仕様に対する理解を深めていきたいです。

Webページから指定したタグの要素を抜き出すRuby関数

単一のWebページから抜き出した複数の要素を配列に格納して返します。
以下の例はaタグの要素(エレメント)を抽出した場合です。

Rubyコード

学んだこと

  • Net::HTTP.startメソッドをブロックを用いて呼び出すことによって、ブロックの間だけセッションを開いて接続し、ブロック終了とともに自動的にセッションを閉じる。Rubyに慣れてもJavaやCでの手続きを意識しておくこと。
  • 配列の結合には和集合(演算子は「|」)を用いた。この場合、重複する要素は1つとして数えられる。別々に数えたい場合は「+」演算子を用いる。
  • String#scanメソッドはブロックで用いるとブロック変数にマッチした部分を格納する。その際、正規表現の中で「()」が用いられると、()内の部分を配列にして返す。今回は別に配列にする必要はなかったかも。

参考サイト

Web サーバからドキュメントを得るRubyist Magazine – 標準添付ライブラリ紹介 【第 7 回】 net/http

タグの中の要素を抜き出すRuby関数

ライブラリを使えば簡単ですが、正規表現の学習の為に。

ソースコード

ここで学んだことは、正規表現の規則中に変数を用いる際は#{var_str}と表記すること。

POSTメソッドを用いてExcite翻訳を行うRubyコード

しかし、未完です。

Webの巡回などにはWWW::Mechanizeという便利なライブラリがありますが、あえてnet/httpのPOSTメソッドを使う理由は、単にPOSTそのものと正規表現の学習をするためです。

今回は正規表現で試行錯誤。

Rubyソースコード

実行結果

ここで、正規表現

/"after"[^>]*>(.*)/ism

の部分を

/"after"[^>]*>(.*)< \/textarea>/ism

に変更するとマッチしなくなってしまいました。
オプション指定のmで複数行にマッチするはずなんですが・・・うーん、何を見落としているのだろう。

Rubyで引数の設定値によって4パターンの部分文字列を取得するラッパー関数

引数に設定値を与え、それによって挙動を変えることで、似た機能をまとめてみます。

追記(2008.2.8):正規表現のマッチを保持する変数があったことを失念していました。「$`」マッチした部分より前の文字列、「$&」マッチした文字列、「$’」マッチした部分より後ろの文字列を使えばより簡潔に書けると思いました。

ソースコード

実行結果

単に部分文字列を取得するには

Ruby: メソッドの引数にブロックを渡す

ブロックの使い方を練習してみます。

メソッドに渡したブロックはyieldを用いて呼び出します。
似たような例としてもう一つ。

渡されたブロックはProcオブジェクトに変換されるのでcallを用いて呼び出すことも出来ます。下の例で確認してみます。

最後に、渡されたブロックをまた引数として渡す場合の例を示します。
その際、ブロック変数名の前に「&」をつけます。