• 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  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

いくつか前のOSアップデートのころから

   1  % ping localhost
   2  ping: cannot resolve localhost: Unknown host

という状態になっていたて原因が分からず放置していましたが、 /etc/hosts の中に IPv6用の設定があるのが原因のようです。

   1  ::1             localhost

これをコメントアウトすると正常な動作に戻りました。

posted by Png genki on Sun 31 Jul 2011 at 18:16

Rubyのリファレンスを参照するときは、いつもGoogleで検索していたのですが、なぜか検索結果からのリンクがリンク切れに。 昔のリファレンスは

  • http://www.ruby-lang.org/ja/man/html/*

にあったのですが、以下のように新しいURLに移動したようです。

旧版は以下に移動した模様。

検索インデックスが新しくなるようにGoogle botに頑張って欲しいです。

See Also

posted by Png genki on Thu 21 Jul 2011 at 13:29

bundlerを使ってnative extensionを含むGemをインストールする場合に、 オプションの指定が必要な場合は ~/.bundle/config などを使いますが、 例えば Mac 環境で do_postgres をbundle installするには、以下のように 設定します。

   1  BUNDLE_BUILD__DO_POSTGRES:
   2    --with-opt-dir=/Library/PostgreSQL/9.0
   3    --with-opt-include=/Library/PostgreSQL/9.0/include/postgresql/server

posted by Png genki on Wed 20 Jul 2011 at 19:09

古いバージョン(1.2.6)ではこの問題は起こらなかったのですが、 ubuntu-11.04の1.4.5では、しばらく使っていると/tmp/tmp.XXXXX というディレクトリが大量に残るという問題があるようです。 調べてみたのですが、あまり似たような報告がなかったので、 特定の条件が揃った場合だけ発生する問題なのかもしれません。

とりあえず、以下のような力技で対処。

cleanup_munin_tmp

   1  #!/usr/bin/env ruby
   2  require "etc"
   3  
   4  Dir['/tmp/tmp.*'].each do |path|
   5    uid = Etc.getpwuid(File.stat(path).uid).name
   6    gid = Etc.getgrgid(File.stat(path).gid).name
   7    next if uid != 'nobody'
   8    next if gid != 'munin'
   9    system "rmdir --ignore-fail-on-non-empty #{path}"
  10  end

これをcronで@hourlyに実行してます。

追記

シェルスクリプト版も用意してみました。

   1  #!/bin/sh
   2  
   3  for d in /tmp/tmp.*
   4  do
   5    if [ `stat -c %U $d` = "nobody" ]  
   6    then
   7      if [ `stat -c %G $d` = "munin" ]
   8      then
   9        rmdir --ignore-fail-on-non-empty $d
  10      fi
  11    fi
  12  done

posted by Png genki on Thu 7 Jul 2011 at 21:05

ActiveRecordを読み込んだ状態でirbを使っているときに、TAB補完をしようとすると落ちることが結構な頻度でありました。 原因を調べてみると、補完候補のArrayをsort使用としているところで、Symbolに対して <=> 演算子を呼びだそうとしてエラーが発生しているようです。 補完候補は Object#instance_methods から得ているようなので、なぜSymbolが要素として混入するのかが謎だったのですが、どうやら Arel::Attribute::Predications クラスが犯人のようです。

   1  PREDICATES = [
   2    :eq, :eq_any, :eq_all, :not_eq, :not_eq_any, :not_eq_all, :lt, :lt_any,
   3    :lt_all, :lteq, :lteq_any, :lteq_all, :gt, :gt_any, :gt_all, :gteq,
   4    :gteq_any, :gteq_all, :matches, :matches_any, :matches_all, :not_matches,
   5    :not_matches_any, :not_matches_all, :in, :in_any, :in_all, :not_in,
   6    :not_in_any, :not_in_all
   7  ]
   8  
   9  Predications = Class.new do
  10    def self.instance_methods *args
  11      warn "this module is deprecated, please use the PREDICATES constant"
  12      PREDICATES
  13    end
  14  end

このコードを書いた人は instance_methodsはStringの配列を返すという事を失念していたようですね。 irb/completeはObjectSpaceから補完候補を拾ってくるので、上述のコードがあるせいでSymbolが補完候補配列に混入してしまいます。

回避策としては、irb起動時に以下のようなコードを読み込むなどがあります。

   1  module Arel
   2    class Attribute
   3      class Predications
   4        def self.instance_methods
   5          require 'arel/algebra/attributes/attribute'
   6          Arel::Attribute::PREDICATES.map(&:to_s)
   7        end
   8      end
   9    end
  10  end

追記

この問題は 1.8.x系のRubyでのみ発生するようです。 thanks @a_matsuda!

posted by Png genki on Thu 7 Jul 2011 at 12:47
Contents
Rubyでメソッド引数が省略されたかどうか判別する方法
MacOS10.6.8でSocket.getaddrinfoが不安定になる問題
同一構造のStructの再定義問題を回避する
class_evalとclass_execの違い
kyotocabint-ruby
Macでping localhostが通らなくなった場合の対処法メモ
RubyのオンラインリファレンスのURLが移動
Mac環境のbundlerでdo_postgresをインストールする
muninを使っていると/tmp/tmp.XXXXXが大量に残る問題
AR使用時にirbで補完しようとするとクラッシュする問題
Comments
瀧内元気: MacOS版は以下にあります * [genki/ViMouse](https://githu... '23-1
dsjf: https://gist.github.com/6bf1bf2c3cbb5eb6e7a7 これ... '13-1
瀧内元気: おお、チェックしてみます。thx! '11-12
overisland: Reeder for iPhone もこの UI を実装していますね。 '11-12
瀧内元気: その情報は見たのですが、以下のサイトによると、現在はまた必要になってるっぽいんですよね。 ... '11-12
Services from s21g
twpro(ツイプロ)
Twitterプロフィールを快適検索
地価2009
土地の値段を調べてみよう
MyRestaurant
自分だけのレストラン手帳
Formula
ブログに数式を埋め込める数式コミュニティ