ActiveSupportのRange拡張
active_support/core_ext/range/ 以下をざっとみてみた。
include_with_range.rb
Range#include_with_range?(val)はvalがRangeじゃなかったら単純にincludeしてるかを
判断し、Rangeだった場合はレシーバの範囲内に収まっているかどうかを検証する。
irb(main):005:0> require "active_support/core_ext/range" => [] irb(main):007:0> (1..10).include_with_range?(3) => true irb(main):008:0> (1..10).include_with_range?(11) => false irb(main):009:0> (1..10).include_with_range?(2..9) => true irb(main):010:0> (1..10).include_with_range?(2..11) => false irb(main):011:0> (1..10).include_with_range?(0..11) => false
overlaps.rb
Range#overlaps?(val)はvalがレシーブの一部にでも含まれているかどうかを検証する。
irb(main):015:0> (1..10).overlaps?(9..11) => true irb(main):016:0> (1..10).overlaps?(2..10) => true irb(main):017:0> (1..10).overlaps?(11..12) => false
conversions.rb
これはどの拡張クラスにもつくみたい。
Range#to_formatted_s(format=:default)はformat=:defaultでRangeのto_sをそのまま呼ぶ。
format=:dbを指定した場合Procが呼ばれてDBに問い合わせる文字列が帰る。
irb(main):004:0> (1..10).to_formatted_s => "1..10" irb(main):003:0> require "active_support/time" => true irb(main):004:0> date_range = Date.new(2012,8,16)..Date.new(2012,8,20) => Thu, 16 Aug 2012..Mon, 20 Aug 2012 irb(main):009:0> date_range.to_s(:db) => "BETWEEN '2012-08-16' AND '2012-08-20'" irb(main):010:0> date_range.to_formatted_s(:db) => "BETWEEN '2012-08-16' AND '2012-08-20'"
ActiveSupportのArray拡張
active_support/core_ext/array/ 以下をざっとみてみた。
prepend_and_append.rb
<< -> appendに unshift -> prependにalias張る。
access.rb
要素にアクセスしやすいヘルパーみたいなもの。
Array#forty_two っていつ使うんだろ・・・
irb(main):012:0> require "active_support/core_ext/array/access" => false irb(main):013:0> pochi = %w(p o c h i) => ["p", "o", "c", "h", "i"] irb(main):014:0> pochi.from(2) => ["c", "h", "i"] irb(main):015:0> pochi.to(2) => ["p", "o", "c"] irb(main):017:0> %w(second third fourth fifth forty_two).each {|m| puts pochi.__send__(m) } o c h i => ["second", "third", "fourth", "fifth", "forty_two"] irb(main):018:0>
uniq_by.rb
Deprecation出てる。Array#uniq読んでるだけ。
wrap.rb
何でもArrayっぽくしてくれる。
irb(main):020:0* require "active_support/core_ext/array/wrap" => true irb(main):021:0> Array.wrap(nil) => [] irb(main):022:0> Array.wrap("pochi") => ["pochi"] irb(main):023:0> Hoge = Class.new() => Hoge irb(main):024:0> Array.wrap(Hoge) => [Hoge] irb(main):025:0>
extract_options.rb
よくRailsだと引数の最後はHashにすることがあるのでそれだけ取り出す
Array#extract_options!で取り出すことができる。
さりげなくHashに自分がHashインスタンスか確認するextractable_options?が定義されてる。
irb(main):025:0> require "active_support/core_ext/array/extract_options" => true irb(main):026:0> array = ["pochi", "kyoto", age: 11] => ["pochi", "kyoto", {:age=>11}] irb(main):027:0> array.extract_options! => {:age=>11} irb(main):028:0> array = ["pochi", "kyoto"] => ["pochi", "kyoto"] irb(main):029:0> array.extract_options! => {} irb(main):030:0>
grouping.rb
Array#in_groups_of(number, fill_with=nil)はfill_withがfalseならeach_sliceを呼ぶだけで
fill_withがある場合は必要個数分concatしてからeach_sliceを呼ぶ。
当然blockにも対応
irb(main):033:0> require "active_support/core_ext/array/grouping" => true irb(main):035:0> (1..10).to_a.in_groups_of(3, "pochi") => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, "pochi", "pochi"]] irb(main):036:0> (1..10).to_a.in_groups_of(3) => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, nil, nil]] irb(main):037:0> (1..10).to_a.in_groups_of(3, false) => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] irb(main):038:0> (1..10).to_a.in_groups_of(3, 4) { |g| puts g.max } 3 6 9 10 => nil irb(main):039:0>
Array#in_groups(number, fill_with=nil)はArray#in_groups_ofに似てるけど
fillする挙動が違う。
irb(main):040:0> (1..10).to_a.in_groups(3, "pochi") => [[1, 2, 3, 4], [5, 6, 7, "pochi"], [8, 9, 10, "pochi"]] irb(main):041:0> (1..10).to_a.in_groups(3) => [[1, 2, 3, 4], [5, 6, 7, nil], [8, 9, 10, nil]] irb(main):042:0> (1..10).to_a.in_groups(3, false) => [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] irb(main):043:0> (1..10).to_a.in_groups(3, 4) { |g| puts g.max } 4 7 10 => [[1, 2, 3, 4], [5, 6, 7, 4], [8, 9, 10, 4]] irb(main):044:0>
Array#split(value=nil, &block)ということで条件をみてArrayを配置してくれる。
splitのコードはtapのほうが好きだけどblockの使い方は勉強になる。
irb(main):044:0> ["hoge", "moge", "fuga"].split("moge") => [["hoge"], ["fuga"]] irb(main):045:0> ["hoge", "moge", "fuga"].split {|message| message == "moge" } => [["hoge"], ["fuga"]] irb(main):046:0>
conversions.rb
Array#to_sentence(options={})はそれっぽい文字列に変換してくれる。
localeをオプションに連結文字を変更できる。
irb(main):047:0> require "active_support/core_ext/array/conversions" => true irb(main):048:0> ["pochi", "miitan", "mineko"].to_sentence => "pochi, miitan, and mineko" irb(main):050:0> ["pochi", "miitan", "mineko"].to_sentence(words_connector: ' and ', two_words_connector: ' too ', last_word_connector: ' after all ') => "pochi and miitan after all mineko" irb(main):051:0> [].to_sentence => "" irb(main):052:0> ["pochi", "miitan"].to_sentence => "pochi and miitan" irb(main):053:0>
Array#to_formatted_s(format = :default)はオブジェクトが詰まってる配列を
to_sを読んで文字列にしてくれる。
DBを渡してあげるとid返してくれたりする。
irb(main):059:0> class Person; attr_accessor :name; def to_s; name; end; end => nil irb(main):060:0> pochi = Person.new => irb(main):061:0> pochi.name = "pochi" => "pochi" irb(main):062:0> miitan = Person.new => irb(main):063:0> miitan.name = "miitan" => "miitan" irb(main):064:0> [pochi, miitan].to_formatted_s => "[pochi, miitan]" irb(main):065:0> class Person; attr_accessor :id; end => nil irb(main):066:0> pochi.id = 3 => 3 irb(main):067:0> miitan.id = 2 => 2 irb(main):068:0> [pochi, miitan].to_formatted_s(:db) => "3,2" irb(main):069:0>
Array#to_xml(options={})は配列からxmlを生成してくれる。
ActiveSupport::XmlMiniってのを使ってるみたい。
irb(main):070:0> [pochi, miitan].to_xml => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<people type=\"array\">\n <person type=\"Person\">pochi</person>\n <person type=\"Person\">miitan</person>\n</people>\n" irb(main):071:0>
Notificationsの使い方
FirefoxでNotification を利用できるようになり、(Chromeはデフォルトで実装されてる)今後実装する機会も多くなりそうです。Google先生に聞いてみるとdesktopifyが有名ですが中身を見ると自分で実装した方が早い気がしてます。簡単に以下使い方をメモで残しておきます。
今回確認する用のアプリ
今回はRails 3.1.0rc1で簡単なアプリを作ってみました。
簡単ですが、以下の流れで確認していきます。
- クライアントにデスクトップ通知の確認を実施
- 現状の通知状態を確認
- 実際に通知してみる
クライアントにデスクトップ通知の確認を実施
画面のActivateを選択すると以下のダイアログができてデスクトップ通知を有効にするかどうか確認します。
ここのコードはこんな感じです。(CoffeeScriptです)
$(document).ready -> $("#activate").live("click", -> window.webkitNotifications.requestPermission() ) <button id="activate">Activate</button>
上記のwindow.webkitNotifications.requestPermission()を呼べばユーザさんに確認できます。
現状の通知状態を確認
画面のConfirmを選択すると以下のダイアログができてデスクトップ通知を有効にするかどうか確認します。
ここのコードはこんな感じです。(CoffeeScriptです)
$(document).ready -> $("#confirm").live("click", -> alert(window.webkitNotifications.checkPermission()) ) <button id="confirm">Confirm</button>
0がユーザに許可されている状態、2がユーザが拒否している状態です。
実際に通知してみる
画面のNotification!を選択すると実際に通知が表示されます。
ここのコードはこんな感じです。(CoffeeScriptです)
$(document).ready -> $("#notification").live("click", -> window.webkitNotifications.createNotification("mail.png", "pochi", "bowbow!").show() ) <button id="notification">Notification!</button>
showメソッドで表示することができます。
Thorで書いたタスクのテストをする方法
Thorでタスクを書くとそのメソッドが普通のRubyのようには呼べません。それでもやっぱりテストは書きたいのでThorのspecをいろいろ見てたらありました。
# encoding: utf-8 require "rubygems" require "thor" require "rspec" require "stringio" class Sample < Thor desc "name", "sample name" def name puts "pochi" end end describe Sample do it "should display 'pochi'" do capture(:stdout) { Sample.new.invoke("name") }.strip.should == "pochi" end end