sinatraset :foo, 'bar'みたいなDSLを使って値を設定できる。でもこの値ってどこにどうやって保存されているんだろう?

普通、最終的にはインスタンス変数かクラス変数に格納されてるって思うよね。

(class << self; self; end).class_eval do
  undef_method(name) if method_defined? name
  String === content ? class_eval("def #{name}() #{content}; end") : define_method(name, &content)
end

sinatra/lib/sinatra/base.rb at v1.4.5 · sinatra/sinatra

ところがset :foo, 'bar'するとbarを返すfooというメソッドが定義されるという形で保存されている。

setするたびにundef_methodして定義し直すので変数みたいに使えるようだ。静的な頭で考えてたのでクラクラするような格納方法だ。

$LOADED_FEATURESっていうのがある。

% pry
[1] pry(main)> $LOADED_FEATURES
=> ["enumerator.so",
 "/usr/local/opt/rbenv/versions/2.1.0/lib/ruby/2.1.0/x86_64-darwin13.0/enc/encdb.bundle",
 "/usr/local/opt/rbenv/versions/2.1.0/lib/ruby/2.1.0/x86_64-darwin13.0/enc/trans/transdb.bundle",
 "/usr/local/opt/rbenv/versions/2.1.0/lib/ruby/2.1.0/x86_64-darwin13.0/rbconfig.rb",
 "/usr/local/opt/rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/compatibility.rb",
 "/usr/local/opt/rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/defaults.rb",
 "/usr/local/opt/rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/deprecate.rb",
 "/usr/local/opt/rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/errors.rb",
 "/usr/local/opt/rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/version.rb",
(snip)

ほうほう。

rubygems - How do I get a list of files that have been `required` in Ruby? - Stack Overflow

$ brew install dart
$ which dart
/usr/local/bin/dart

hello.dart:

#!/usr/bin/env dart

void main() {
  print('Hello Dart.');
}
$ chmod u+x hello.dart
$ ./hello.dart
Hello Dart.

ニコニコ動画はもっぱらWindowsの専用ブラウザーnFinder2で見ていたんですが、ウォッチ中のマイリストが200を超え、Macや特に寝る前のiPad miniでも見たいのでnFinderのお気に入りをOPMLにエクスポートするスクリプトを書きました。

そもそも動画プレイヤーは何でもよくて、はてなアンテナのような更新監視にのみ使っていたので。

nFinder2のお気に入りをOPMLにエクスポートする - gist.github.com

これを普段とは別アカウント/別ブラウザのFeedlyにimportすれば他のプラットフォームでマイリストの更新監視が捗ります。

続きが気になっていたシリーズ物が2年失踪後に復活とかがよくあるので見逃せません。

でもよく考えると2009年にRemedieでやっていたことがクラウドに移行しただけですね。

Remedie - Debian etch - komagata

時間を表示する時に、rails標準の〜日前とかではなく、現在時刻を基準に

5月2日 # 同じ年だったら
2日 # 月まで同じだったら
10時20分 # 日まで同じだったら
20分 # 時間まで同じだったら

という感じでコンパクトに表示したいという要件があったのでgemにしました。

komagata/time_compact

ActiveRecordのデフォルトではORDER BY区は省略されてるので、「ポスグレでデフォルトの並びってどうなってるんだろう?」と思って調べました。

SELECT - PostgreSQL 9.3.2文書

ORDER BYが指定されない場合は、システムが計算過程で見つけた順番で行が返されます

(略)

ORDER BY句を使うと、結果行を指定した式(複数可)に従ってソートすることができます。 最も左側の式を使って比較した結果、2つの行が等しいと判断された場合は、1つ右側の式を使って比較します。その結果も等しければ、さらに次の式に進みます。 指定した全ての式で等しいと判断された場合は、実装に依存した順番で返されます。

なんとなくINSERT順で出るのでは?と思ってましたが、実装依存なようなので、並びに意味がある箇所では必ず明示的に指定したほうが良さそうです。

SQL92や99、MySQLやSQLiteではどうなってるんだろう?

default_scopeでid ascとかにしとくべきか?でもARのdefault_scopeってバグを踏みやすい勝手な印象が付いてしまっていて過信するのもためらわれる…。

弊社インターンの @odailly_jp さんのお陰でLingrにHubotが設置され、従来のLingr Github Botではできなかったコメントの通知が来るようになった。(IssuesやPRのコメントを拾ってくれるPluginを作ってくれたので。)

odaillyjp/hubot-github-comments-notifier

便利ー!

第二世代?のエラートラッキングサービスrollbarを設定してて気付いたんですが、EngineYardCloudのAddonsのページが新しくなってて、新しい方にはrollbarが入ってる。

Instructionsのページの設定だけだとデプロイ通知はやってくれないっぽいのでdeploy hooksで送るように追記してみました。

# deploy/after_restart.rb:
require 'rubygems'
require 'bundler/setup'
require 'net/https'

on_app_master do
  rollbar_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
  uri           = URI('https://api.rollbar.com/api/1/deploy/')

  Net::HTTP.post_form(uri, 'access_token'   => rollbar_token,
                           'environment'    => config.framework_env,
                           'revision'       => config.revision,
                           'local_username' => 'deploy')
end

OK。

EngineYardCloudのdeploy hooksを使ってLingrに通知してますが、怖話っぽくしてみました。

Engine Yard Cloudでデプロイした時Lingrに通知する - komagata

WebPayはrubyistにとっては課金が糞楽になるので便利。

特に便利なのがCheckoutHelpertというやつで、カード入力フォームがJSを一個読み込むだけでできる。

しかもこいつはクライアント上のjsがwebpayと直接やりとりするのでカード情報が一切サーバーに来ないという優れもの。(代わりにwebpay上にある顧客情報に紐づくトークンを得る)

しかし、お客さんから「サイトの見た目とトンマナを合わせて欲しい」という要望が。まあ当たり前の要望だと思う。俺も思うもん。

CheckoutHelperは表示するためのボタンがあってそれをクリックしてはじめて上記のオーバーレイ付きのフォームが出る。場所も固定だ。そしてDOM Elementとしてもbodyの一番したにある。

そこでjsでボタンをクリックしてこの#webpay-checkoutのElementをrailsのフォームの中に移動してみた。

$('#WP_checkoutBox input[type=button]').click();
$('#webpay-checkout').appendTo('#new_card')

こうした上でCSSでposition: absoluteやら何やらを切ってやれば普通のフォームに見えるかも。

こういう見た目のカスタマイズがやりやすいようになってると嬉しいな。

ちょっとした要望

上記のCheckoutHelperのフォームはonsubmitイベントが呼ばれない。(ブラウザによる?)フックしたい時にちょっと不便だった。CheckoutHelperのソース読んだが、生jsのsubmitしてるだけなのでそうなってるんだとおもう。

jQueryはどのブラウザでもonsubmitが呼ばれるようになってたと思う。これ呼んでほしいな。