October 30, 2007

ruby-debug 入門(僕が)

ruby-debug ってのをちょこっと使ってみました。
結構お手軽で便利かもしれません。

ていうか、デバッグツールとしては rails の breakpointer みたいなのでとりあえず十分なんだけど、あれって rails 以外で単体で使ったりできないのでしょうか。
ま、ruby-debug を使えば似たようなことできるのでいいんですけど。

インストールと起動

以下のような感じでインストール。

gem install -y ruby-debug

そしたら以下のようなコードを書いて実行してみてください。

require 'rubygems'
require 'ruby-debug'

a = "hoge"
debugger # デバッガ起動
puts a
a = "hage"
puts a

すると debugger って書いてあるところで止まります。
このときプロンプトにこんなのが表示されると思います。

(rdb:1) 

この状態でいろいろデバッガのコマンドを実行することができます。
とりあえず「help」コマンドを実行してみてください。
なんかいろいろ表示されると思います。

例えば、「p」コマンドで変数の内容を出力したり、「list」コマンド でソースを表示させたりできます。
あと、まだ実験段階らしいのですが、「irb」コマンドで irb のセッションを開始したりできるようです。
irb の方が(僕が)慣れているのでいいですよね。

参考: Ruby On Rails ピチカート街道 – デバッグ初体験03【ruby-debug v0.9.3 マニュアルお気楽翻訳】 -

デバッガの起動方法として、rdebug コマンドと使うというやりかたもあります。
ruby コマンドの代わりに rdebug コマンドでプログラムを実行します。
こんな感じ。

rdebug debug_test.rb

ruby-debug の利点

ていうか、ruby にはもともと標準のデバッガがあるわけですが、それと比べた場合の ruby-debug の利点って何なんですかね。
挙げるとしたら以下の点ですかね。

  1. debugger メソッドにより、breakpointer みたく任意の場所でデバッガを起動できる
  2. irb セッションを起動できる

1 に関しては、プログラムに「require ‘ruby-debug’」ってのを書かないといけないという煩わしさがあります。
あと、まあ、まだ使い方を調べただけで実際にそんなに使い倒してないので正直なんとも言えませんが、なんかこう、デバッガって言うと取っ付きにくいイメージが(僕の中では)ありますが、ruby-debug は(僕の中では)比較的取っ付きやすい気が(なんとなく)します。

これも参考になるかもしれません。
Local Insanity » Ruby Debug Basics [screencast]

ruby-debug の基本的な使い方のスクリーンキャストです。

October 16, 2007

同じメソッドを連続で呼び出すためのメソッドを作ってみた(ruby)

同じメソッドを続けて何回も呼びたい時ってないですか?
gsub を何回も呼んだリだとか。

えーと、例えばこんなようなコードを書いたりしたことないですか?

puts "hoge".gsub("h", "H").gsub("o", "a").gsub("e", "eee!!!!") #=> Hageee!!!!

ありますよね。
「gsub」を何回も書いててかっこわるいですね。
どうせ同じメソッドを続けて呼ぶんだから、「gsub」と書くのは一回きりにしたいですよね。

そこでこんな関数を考えました。

class Object
  #
  # 同じメソッドを引数のバリエーションの数だけ呼び出します
  #
  def send_c(name, *args_list)
    result = self
    args_list.each{|args|
      result = result.send(name, *args)
    }
    result
  end
end

ちなみに、メソッド名「send_c」の「c」は「continuously」だかなんだかの「c」。

こんなふうに使います。

# 使用例
puts "hoge".send_c(
    :gsub,
    ["h", "H"],
    ["o", "a"],
    ["e", "eee!!!!"]
) #=> Hageee!!!!

うん。
便利便利。

これ、役に立ちますかねぇ。。

October 10, 2007

プログラミングって、要は

プログラミングって、要は「会話」なんなんだと思います。
プログラムを書くことを通していろんな人と会話するわけです。
会話の相手は、プログラミング言語やライブラリ、フレームワーク等を作った人達や、その他いろいろです。
プログラマーは、相手の意図をできるだけ正確に読み取る必要があります。
それが上手くできないと、ちゃんとしたプログラムは書けないと思います。

具体的に言うと、HTML の仕組みとかスタイルシートの仕組みとか、なぜそんなふうになったのかとか、そういったようなことをきちんと理解している必要があるということです。
そういった諸々の仕様は、誰かの意図があってそうなったわけですよね。
その意図をちゃんと読み取らないとだめなんです。

ああ、なんか、当たり前のこと言ってますね。

October 9, 2007

それ、プロとしてどうなの

愚痴:

「それ、プロとしてどうなの」と言いたくなるような、そんなプログラムを最近たびたび見かけます。
ま、僕自身もそんな偉そうなこと言えるレベルにはまだまだ達してませんが、そんな僕から見てもあきらかに「ひどい!」と思えるような、そんなプログラムを書いてしまう人が世の中にはいるんですね。
プロとしてまだまだ未熟な僕ごときに「プロとしてどうなの」というようなことを言わせてしまうような人は、本当にプロとしてどうなのかと思いますよ。
自分が作った部分がとりあえず動けばそれでいいんですかね。

ひどいプログラムを見た時は、まず何よりもその人の美的感覚を疑ってしまいます。
インデントがちゃんとそろっていなかったりだとか、意味のわからない変数名がたくさんあったりだとか。
あと、不要なコードが削除されずに放ったらかしになってたりするのも許せないですね。

まったくもう。

と言いつつ、ダメプログラムをガシガシ直していくのは楽しくもあります。
テストしながら慎重に作業を進めていく必要がありますが。
自分の新しい実装でシステムが正常に動作するとかなり嬉しくなりますね。

September 23, 2007

ruby の Hash に Array みたいな join メソッド

ruby の Hash に Array みたいな join メソッドがあったら便利な状況がきっとあるはず。

#!/usr/bin/env ruby

class Hash
  def join(str1, str2)
    array = []
    self.each{|k, v|
      array << k + str1 + v
    }
    return array.join(str2)
  end
end

hash = {"cat"=>"3", "paged"=>"2"}
puts 'http://jugyo.org/blog/?' + hash.join("=", "&")

#=> http://jugyo.org/blog/?cat=3&paged=2

追記:
もうちょい簡潔に書けた。

class Hash
  def join(str1, str2)
    to_a.collect{|array|
      array.join(str1)
    }.join(str2)
  end
end
September 21, 2007

ruby で http のタイムアウトを延ばす

ruby で http による通信を行う場合、サーバから一定秒数(デフォルト 60秒)レスポンスが返ってこないとタイムアウトエラーが発生する。
以下のように read_timeout を変更することでタイムアウトの秒数を延ばすことができる。

Net::HTTP.start('hoge.com', 80) {|http|
  http.read_timeout = 120
  ...
}

でも例えば、アプリケーション全体でこの read_timeout を変えたくなったりした場合、毎回「read_timeout = 120」とか書くのは面倒くさい。
しかも open-uri の open メソッドなんかを使ってる場合、http なんか出てこない(意識しない)から read_timeout を設定しようがない。

read_timeout は HTTP クラスのコンストラクタの中でデフォルト値として 60秒に設定されている。
これをなんとかして任意の値に変えることはできないかな。

できた。

class Net::HTTP
  def initialize_new(address, port = nil)
    initialize_old(address, port)
    @read_timeout = 120
  end
  alias :initialize_old :initialize
  alias :initialize :initialize_new
end

この処理をはじめに実行しておくとタイムアウトの秒数がデフォルトで 120秒になる。

けど、かなり強引。
はたしてこんなやり方でいいんだろうか。

September 15, 2007

Flash やることに

どういうわけか、既存の Web アプリの Flash 部分の改修をやることになりました。
Rails と Ajax で四苦八苦してるのにその上 Flash。
「Flash ってどうやってデバッグするんだろう?」ってところからスタートです。

ログ出力の方法についてまず調べました。
trace っていう関数でログ出力できるみたいです。

trace("ログ...");

ていうか、ソース読んでてこれログ出力以外にないだろ、と察しました。
わかりやすくて良いですね。

で、そのログは一体どこに出力されるのか。
しばらく考えましたが、そもそも Flash アプリケーションは、ブラウザがサーバからダウンロードしたファイル(*.swf)をローカル環境で実行することによって動くわけだから、当然ログは手元のマシンのどこかに出力されるはずですよね。

結論をいうと、ログは以下のディレクトリに出力されます(Windows の場合)。

C:¥Documents and Settings¥user_name¥Application Data¥Macromedia¥Flash Player¥Logs¥flashlog.txt

でも、普通に Flash をブラウザで実行するだけじゃダメで、デバッグ用の Flash Player (flash debug player)をインストールし、設定ファイルを作成し、そこにログ出力のための設定を書き込んだりといった手順を踏む必要があります。
手順の詳細については以下が参考になりました。

参考: カサヒラボ – windowsやmacで、flashのtraceログが吐かれる場所

出力されるログを Firefox 上で見る為のアドオンなんかもあります。

FlashTracer :: Firefox Add-ons

フィルタリングの機能があってそこそこ便利です。

Flash の開発環境についてまた後で書くと思います。