Enumerable#grepを使う事で、文字列の配列から、 所望のパターンにマッチするものだけを抜き出す事が出来ますが、 以下のようにブロックを指定する事で、 マッチした部分だけを取り出す事が出来ます。

   1  Dir["config/environments/*.rb"].grep(%r{(\w+)\.rb$}){$1}
   2  #=> ["development", "production", "rake", "staging", "test"]

痒いところに手が届く感じですね。

posted by Png genki on Thu 30 Apr 2009 at 14:32

Sassを使うようになって、属性とタグの区別がつきにくいなと感じていたので、シンタックスハイライトをする方法を探してみました。

これを使うと、こんな感じになります。

ss

だいぶ見やすくなりました。

posted by Png genki on Sun 26 Apr 2009 at 17:34

例えばJavaScriptだと"\u3000"と書けば良かったのですが、少なくともRuby-1.8系ではこれに相当する記法が無さそうだったので、いつも困ってました。 色々調べてみた結果、以下のようにすれば良さそうです。

   1  [0x3000].pack("U") == " "  #=> true

長い事迂回していた問題だったのでスッキリしました :-)

Special Thanks

  • @yukiko pack("U")が使えそうという情報をありがとうございます。
posted by Png genki on Fri 24 Apr 2009 at 06:28
posted by Png genki on Thu 23 Apr 2009 at 21:12

Rails勉強会#40のセッションでも言いましたが、 エラーが発生した時等に表示されるbacktraceの表示は、 コンソールのように上から下に流れる画面上では 通常の逆順のほうが追いやすいと思います。

ということで、ちょっと試しにそのような挙動にしてみました。 以下のようなコードを実行するとテストできます。

   1  class Exception
   2    def set_backtrace(bt)
   3      puts bt.reverse.map{|i|
   4        i.sub(/^([\/\.\w]+):(\d+)/,
   5          "\e[33m\\1\e[m:\e[32m\\2\e[m")
   6      }.join("\n")
   7    end
   8  end
   9  
  10  def foo
  11    raise StandardError
  12  end
  13  
  14  def bar
  15    foo
  16  end
  17  
  18  bar

こんな感じに、エラーが発生した場所に近い順に、 下から上にたどっていく感じに表示されます。

ss

上から下のbacktraceに目が慣れてしまっているので、最初は追いかけにくさを感じますが、一旦慣れてしまえば、スタックが深くて相当スクロールアップしなければエラーの発生源までたどり着けないという場合には良さそうな気がします。

stackという概念のイメージのせいで、新しいものが上の方に来るようになっているのだと思いますが、実用上は新しいものが下にくるこのスタイルの方が便利ではないでしょうか。

posted by Png genki on Thu 23 Apr 2009 at 14:27 with 2 comments

JRubyで相対パスを含む場合に、Jarファイルの中のファイルを読めるようにするためのモンキーパッチの最新版です。

   1  def cleanup_path(path)
   2    if path.to_s.match(/^file:/) && path.is_a?(String)
   3      jar_path, inner_path = path.split('!', 2)
   4      inner_path = File.expand_path(inner_path)
   5      path = [jar_path, inner_path].join('!')
   6    end
   7    path
   8  end
   9  
  10  alias :require_original :require
  11  def require(path)
  12    require_original cleanup_path(path)
  13  rescue Exception => e
  14    raise e unless path.to_s.match(/^file:/)
  15  end
  16  
  17  alias :load_original :load
  18  def load(path)
  19    load_original cleanup_path(path)
  20  rescue Exception => e
  21    raise e unless path.to_s.match(/^file:/)
  22  end
  23  
  24  class Dir
  25    class << self
  26      alias :aref_original :[]
  27      def [](*args)
  28        aref_original *(args.map{|path| cleanup_path(path)})
  29      end
  30    end
  31  end
  32  class File
  33    class << self
  34      alias :mtime_original :mtime
  35      def mtime(path)
  36        if path.match(/^file:/)
  37          jar_file, = path.split('!', 2)
  38          path = jar_file.sub(/^file:/, '')
  39        end
  40        mtime_original(path)
  41      end
  42    end
  43  end

posted by Png genki on Tue 21 Apr 2009 at 02:43

Merbでconfig/router.rbの中で、リソースのカスタムアクションを追加する方法のメモ。

   1  resource :users,
   2    :collection => {:active => :get},
   3    :member => {:password => :get}

:collectionで指定したアクションは、resource(:users, :active) などのように参照できて、"/users/active" のような感じになります。

:memberで指定したアクションは、resource(@user, :password) などのように参照できて、"/users/1/password" のようなスタイルになります。

posted by Png genki on Mon 20 Apr 2009 at 14:57

GAEを使う上での大きな制限として、ファイル数1000までというのがあります。 これを乗り越えるために、unpackしたGemの中から不要なファイルを掃除したりする必要があったのですが、 関連するGem群をjarファイルにまとめる事でこの問題を乗り越えられます。

上記のファイルをlibの下に配置して、config/init.rb あたりでrequire_fixを読み込みます。 これはjarファイルの中のrbファイルの読み込みに関するバグを 回避するためのものです。

実際に以下のサイトでmerb.jarを使って運用しています。

これによって、事実上ファイル数制限に左右されずにアプリケーションを開発する事が出来るようになります。 ただ、1ファイルのサイズ制限(10MB)が存在するので、jarファイルが大きくなりすぎた場合は分割する必要があります。

posted by Png genki on Sun 19 Apr 2009 at 08:46

JRubyを使っていて、JavaのArrayListを作りたい場合には、以下のようにすると良いようです。

   1  java.util.Arrays.as_list([1,2].to_java).getClass.to_s
   2  # => "class java.util.Arrays$ArrayList"

posted by Png genki on Fri 17 Apr 2009 at 11:08 with 2 comments

DataMapper用のDataStoreアダプター、dm-datastore-adapter-0.2.2をリリースしました。

今回のリリースで以下のような機能がサポートされます。

  • トランザクション
  • OR条件
       1  Post.all(:id => [1,2,3])
    
    のような事が出来るようになりました。
  • NOT条件
       1  Post.all(:updated_at.not => nil)
       2  Post.all(:id.not => 3)
    
    などが出来るようになりました。

DataMapperのアダプタとして主に必要な機能はだいたい揃ってきました。

デモサイトであるWatchMe!もアップデートしています。

まだ実用的なサービスになってないですが、登録したサイトをクローリングして全てのページの監視を行い、エラーが発生したらメールで知らせるサービスになる予定です。

posted by Png genki on Fri 17 Apr 2009 at 04:37 with 8 comments