| @技術/プログラミング
@udzura さんがペーパーボーイ社福岡支部に移ってきたこともあって、約半年振りに Fukuoka.rb をやった。前来てたメンバーに加えて初めて参加した人もいた。今日は今後の活動方針なんかを...

@udzura さんがペーパーボーイ社福岡支部に移ってきたこともあって、約半年振りに Fukuoka.rb をやった。前来てたメンバーに加えて初めて参加した人もいた。今日は今後の活動方針なんかを決めた。毎週開催は負担が大きいので隔週へ、継続が大事なので本読みというよりルビー好きな人が集まっておしゃべりしてるような緩やかな会へ、というような提案があった。ルビーコミッターの @nagachika さんが定例を強く復活させたいとおっしゃっていて熱かった。 Asakusa.rb みたいな感じでやれたらいいなと思う。ただ初めて参加した人からは、場所が特定の会社の会議室だと参加しにくい、 AIP カフェなどのパブリックなスペースで、気軽に参加して発表を聞けるような場を設けてはという意見も出たので来年なんかやりましょうという話になった。

自分はこれまでの Facebook での開催告知とかコミュニケーションがあまり好きじゃなかったので、開催告知は Doorkeeper 、コミュニケーションは Lingr でやることになったのが良かった。

@chikanaga さん、 @udzura さんの二大著名ルビーストのおかげで盛り上がりそうな気配ある。第一期は自分の力不足でポシャってしまったけど、これから良いコミュニティになっていけば良いなと思う。

ということで、毎月第二第四木曜の19時から、グルーブノーツ社とペーパーボーイ社で交互に場所をホストしてやることになりましたので福岡市近辺のルビーストの皆さんはぜひお気軽にお越しください。本とか読んでないのでいきなり来ても大丈夫です。

| @技術/プログラミング
[1] pry(2.0.0-p195)> require 'open-uri'[2] pry(2.0.0-p195)> require 'active_support/core_ex...
[1] pry(2.0.0-p195)> require 'open-uri'
[2] pry(2.0.0-p195)> require 'active_support/core_ext/hash/conversions'
[3] pry(2.0.0-p195)> Hash.from_xml(open('http://www.portalshit.net/index.atom').read)
=> {"feed"=>
  {"xmlns"=>"http://www.w3.org/2005/Atom",
   "id"=>"http://www.portalshit.net/",
   "title"=>"portal shit!",
   "updated"=>"2013-06-18T19:07:44+09:00",
   "link"=>
    [{"type"=>"text/html",
      "rel"=>"alternate",
      "href"=>"http://www.portalshit.net/"},
     {"type"=>"application/atom+xml",
      "ref"=>"self",
      "href"=>"http://www.portalshit.net/index.atom"}],
   "entry"=>
    [{"id"=>"tag:www.portalshit.net,2013-06-18T19:04:33+09:00",
      "title"=>"Alfred で Chrome のブックマークを検索する",
      "published"=>"2013-06-18T19:04:33+09:00",
      "updated"=>"2013-06-18T19:07:44+09:00",
      "link"=>
       {"type"=>"html",
        "rel"=>"alternate",
        "href"=>
         "http://www.portalshit.net/2013/06/18/chrome-bookmark-search-with-alfred"},
      "content"=>
       "<p><img src=\"https://resources.portalshit.net/945-chrome-bookmark-search-with-alfred.png\" alt=\"945-chrome-bookmark-search-with-alfred.png (708×295)\
      "author"=>{"name"=>"morygonzalez"}},

で XML の内容を Hash にできる。ActiveSupport 便利。

| @技術/プログラミング
昨日、こういう Pull Request が Lokka に来てた。「あれ、Lokka の master ブランチは Ruby 2.0 対応してないんじゃ」と思って Ruby 2.0.0-p0 ...

昨日、こういう Pull Request が Lokka に来てた。

「あれ、Lokka の master ブランチは Ruby 2.0 対応してないんじゃ」と思って Ruby 2.0.0-p0 で試してみたところ案の定 json.gem のインストールに失敗する。しかしものは試しにと思って、最新のパッチレベルの 2.0.0-p195 をインストールしてみたら Ruby 2.0 で Lokka 起動できた。

というわけでポータルシットは Ruby 2.0 で動いております。

| @技術/プログラミング
以前、Unicorn が暴走して困ってるという記事を書いていた。しかしよくよく調べてみると暴走してるのは Unicorn ではなく、Syntax Highlight に使っている Python ...

以前、Unicorn が暴走して困ってるという記事を書いていた。しかしよくよく調べてみると暴走してるのは Unicorn ではなく、Syntax Highlight に使っている Python の Pygments を呼び出している Ruby のプロセスだった(pygments.rb)。こいつが CPU をバカ食いしてしまい、アプリケーションのレスポンスがすこぶる悪くなっていた。

少し前、Pure Ruby の Pygments 互換 Syntax Highlighter で Rouge というのを発見していたので、Python を spawn するプロセスがなくなれば CPU バカ食いも止まるはず、と思って pygments.rb から移行してみた。しかし…

なんと逆にサイトが重くなってしまった。やはり Pure Ruby のプログラムは重いみたいである。pygments.rb は C のネイティブコードも含んでいて、速さがボトルネックになるところは C で処理しているみたい。

というわけで残念ながら EC2 のマイクロインスタンスで Rouge を常用するのは無理そうなので Pygments + pygments.rb に戻します。あとはキャッシュして誤魔化すしかなさそう。

| @技術/プログラミング
Lokka で Syntax Highlight するプラグイン(morygonzalez/lokka-pygmentize · GitHub)、これまで Ajax で Syntax Highl...

Lokka で Syntax Highlight するプラグイン(morygonzalez/lokka-pygmentize · GitHub)、これまで Ajax で Syntax Highlight させてたんだけど、HTTP リクエストが増えていけてないと感じたのでサーバーサイドでハイライトが完結するように変更した。Railscasts の #272 Markdown with Redcarpet - RailsCasts を参考にして、プラグインの中で Entry クラスを再オープンした。こんな感じ。

class Entry
  def body
    doc  = Nokogiri::HTML(self.long_body)
    doc.search("//pre").each do |pre|
      code = pre.css("code")[0]
      pre.replace Pygments.highlight(
        code.text.rstrip,
        :lexer   => code[:class],
        :options => { :encoding => 'utf-8' }
      )
    end
    doc.to_s
  end
end

前の実装はだいぶいけてなかったと思うので随分マシになったと思う。あと この Pull Request でレンダリングエンジンに Redcarpet が追加されたので、GitHub と同じように

```ruby

```

みたいな感じの書き方でコードがハイライトされるようになった。便利。

追記1

ちゃんと動いてなかった…。夜直します…

追記2 2013/02/04 0:45

最終的にオープンした Entry クラスのコードは以下のようになった。

class Entry
  alias_method :original_long_body, :body
  def highlighted_long_body
    syntax_highlight(self.original_long_body)
  end
  alias_method :body, :highlighted_long_body

  alias_method :original_short_body, :short_body
  def highlighted_short_body
    syntax_highlight(self.original_short_body)
  end
  alias_method :short_body, :highlighted_short_body

  def syntax_highlight(body)
    doc = Nokogiri::HTML(body)
    doc.search("//pre").each do |pre|
      code  = pre.css("code")[0]
      lexer = if pre[:class].present?
                pre[:class]
              elsif code.present? && code[:class].present?
                code[:class]
              else
                nil
              end
      begin
        pre.replace Pygments.highlight(
          code.text.rstrip,
          :lexer   => lexer,
          :options => { :encoding => 'utf-8' }
        ) if code
      rescue MentosError
        next
      end
    end
    doc.to_s
  end
end

Lokka、結構メタプログラミングが多くて、Entry クラスのインスタンスの body メソッドは単なるゲッターではなく、 index アクションのときと show アクションのときで別々にエイリアスが設定されていて、index アクションのときは Entry#short_body 、show アクションのときは Entry#long_body が呼ばれるようになっていた。アラウンドエイリアス使って力業で解決したけど他のプラグインが同じように振る舞ったら破滅を招きそうな気がする…。それにしても『メタプログラミング Ruby』読んでなかったらどうすればいいか皆目検討付かなかっただろうなー。