• 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

ブロック引数を1つとるブロックつき関数を呼び出すときに

   1  create_table do |t|
   2    t.string :foo
   3  end

ブロック仮引数を省略した場合、暗黙のうちにブロック引数に対する instance_eval を挟むようにすると

   1  create_table do |t|
   2    t.instance_eval do
   3      string :foo
   4    end
   5  end

色々と綺麗にかけるようになる気がします。

   1  create_table do
   2    string :foo
   3  end

ついでに、省略されたブロック引数に $ とかでアクセスできると

   1  [1,2,3].map{to_s}.select{$>2}

みたいな事ができて楽しいかもです。 ついでに case の値もこんなふうに

   1  case price # <= この値を $ で参照したい
   2  when $ < 5; #...
   3  when $ < 10; #...
   4  end

参照できるといいな。

posted by Png genki on Wed 31 Aug 2011 at 07:52

前回(uninitialized constant MysqlCompat::MysqlResの対処法参照)はSnow Leopard でしたが、 今回はLionです。 OSのバージョンが変わるたびに問題が起こる気がします。 今回は、以下で回避できるようです。

   1  % install_name_tool -change libmysqlclient.18.dylib /usr/local/mysql/lib/libmysqlclient.18.dylib /path/to/rubygems/gems/mysql-2.8.1/lib/mysql_api.bundle

See Also

posted by Png genki on Wed 31 Aug 2011 at 03:51

EC2のSpotインスタンスの価格変動がどんなものか把握するのが面倒だったので、直近の相場をグラフで表示するwebサービスを作りました。

ss

相場はリージョン、OS毎に違うので、適当な組み合わせを選択してみてください。 データはだいたい5分ごとに更新されています。

実は SpotHistory.com という良さそうな既存サービスがあったのですが、 なぜか1月ぐらいでデータ更新が止まっていて残念な感じだったので、 適当に作ったほうが早そうだということで製作しました。

posted by Png genki on Fri 26 Aug 2011 at 07:38

ブラウザのタブを閉じるときは基本的に中ボタンクリックなので、閉じるボタンの存在は無駄なだけでなく、うっかり押してしまって必要なタブを閉じてしまうこともあって邪魔でした。

そんな場合には、about:config で以下のように値を設定すると、閉じるボタンを非表示にすることができます。

   1  browser.tabs.closeButtons = 2

posted by Png genki on Fri 19 Aug 2011 at 09:24

普段はPostgresqlのサイトで配布されているMac用のインストーラを使っているのですが、どうやらLionはまだサポートされていないようです。

ということで、homebrewを使ってインストールすることにしました。

Homebrewをインストール

以下を実行すればok

   1  /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"

あとは

   1  brew install postgresql

でインストールし、以下でdbを初期化します。

   1  initdb /usr/local/var/postgres

最後に、自動起動の設定を行います。

   1  cp /usr/local/Cellar/postgresql/9.0.4/org.postgresql.postgres.plist ~/Library/LaunchAgents/
   2  launchctl load -w ~/Library/LaunchAgents/org.postgresql.postgres.plist

brewでインストールした場合、postgresユーザは作成されないようです。 $USERがスーパユーザとして作成されます。

posted by Png genki on Thu 18 Aug 2011 at 18:04

以下のようにメソッド引数のデフォルト値を設定すれば、 呼び出す時に省略することができます。

   1  def foo(a = nil)
   2    a
   3  end
   4  
   5  foo #=> nil
   6  foo("test") => "test"

では、引数が省略されたかどうか判別するにはどうすればいいでしょうか。 以下のようにすれば判別が可能です。

   1  def foo(a = (a_default = true) && nil)
   2    [a,a_default]
   3  end
   4  
   5  foo #=> [nil, true]
   6  foo("test") #=> ["test", nil]

Rubyの引数のデフォルト値は、式を記述でき、省略された場合だけ評価されるのでそれを利用できます。

posted by Png genki on Tue 9 Aug 2011 at 04:54

開発環境でしか使っていないので我慢してきたのですが、 どうも MacOS 10.6.8 における Socket.getaddrinfo の挙動が不安定なようです。 以下のように、タイミングによって動作したりしなかったりします。

   1  ruby-1.8.7-p302 :012 > Socket.getaddrinfo("localhost", nil)
   2  SocketError: getaddrinfo: nodename nor servname provided, or not known
   3          from (irb):12:in `getaddrinfo'
   4          from (irb):12
   5  ruby-1.8.7-p302 :013 > Socket.getaddrinfo("localhost", nil)
   6   => [["AF_INET", 0, "en.localhost", "127.0.0.1", 2, 2, 17], ["AF_INET", 0, "en.localhost", "127.0.0.1", 2, 1, 6], ["AF_INET6", 0, "localhost", "::1", 30, 2, 17], ["AF_INET6", 0, "localhost", "::1", 30, 1, 6]] 

MacOS環境でのSocket.getaddrinfoは鬼門なようで、 これまでにも様々な問題が報告されているようですね。

今回は全く同じ条件下で挙動が変わるというものなので、なかなか手ごわい感じです。

posted by Png genki on Sun 7 Aug 2011 at 14:22

RubyのStructは便利なのでよく使いますが、いくつか欠点があります。

  • 無名Structを継承すると、スクリプトのreload時にsuperclass mismatchエラーが出る
  • 同一構造のStructを定義しようとしても別なStructオブジェクトが返ってくる
  • 名前付きStructの場合、Struct::StructName のような名前空間に定義されるので衝突が心配

これらの問題を回避するために、以下のように Struct.[] を定義することにしました。

   1  def Struct.[](*members)
   2    name = members.map(&:to_s).sort.map(&:upcase).join('__')
   3    const_defined?(name) ? const_get(name) : new(name, *members)
   4  end 

これを使って

   1  class Dog < Struct[:name, :age, :height, :weight]
   2  end

のように利用すれば、既に定義済みの場合には定義済みのStructを参照し、そうでない場合には新たにStructを定義するようになるので、上述の問題は解決できます。

なにより、

   1  Struct.new(:name, :age, :height, :weight)

と書くよりスッキリします。

posted by Png genki on Sun 7 Aug 2011 at 00:32

Rubyを使い初めてから結構たちますが、まだ新しい発見というのはあるものですね。

class_evalでブロックを渡す時に、引数も渡したいと思っていたのですが、 class_execはちょうどその目的に使えるようです。

   1  FOO = lambda{|bar| puts bar}
   2  
   3  class Foo
   4    class_exec("Foo", &FOO)
   5  end #=> Foo

posted by Png genki on Sat 6 Aug 2011 at 19:28

kyotocabinet用のRubygemがbuildできない状態になっていたので、 配布元のkyotocabinet-rubyからgemを書き起こしました。

Gemfile

   1  gem 'kyotocabinet-ruby', '~> 1.27',
   2    :require => 'kyotocabinet'

posted by Png genki on Mon 1 Aug 2011 at 04:22