no_picture

Rubyで次の水曜日の18時を取得する

日付処理って意外と面倒である。次の水曜日の18時を取りたい。 ActiveSupport を使っていいのであれば、このように書けた。 require 'active_support/core_ext' Date.today.beginning_of_week(:wednesday) + 1.week + 18.hours 3.0.0 だと beginning_of_week は引数が取れないので注意。3.0 と 4.0 でしか確認してない。

no_picture

広島Ruby勉強会 #031 で 「Hakyllで遊んだ」のでざくっと紹介した。

広島Ruby勉強会 #031 で かるくLT しました。 内容は Hakyll についてです。 なのですが、Rubyのリファレンスからメソッドの紹介をしているのですが、今回は ActiveSupport で追加される メソッド。Array 編をしました。 その資料はこちらに。 この資料をどこにどうやって置こうかな?と思っていたので、ついでにHakyllを試してみました。そこで学んだこととかを紹介しました。 Hakyllで遊んでみた。 from Tomohiko Himura このサイトのソースコードは Github に丸投げしていたりします。 このスライドに書いてないことでは、コンパイルを毎回するのがめんどくさかったので、ghci から 引数付きで main 関数を実行する方法を調べました。 System.Environment に定義されてる withArgs を使えばできました。 withArgs :: [String] -> IO a -> IO a 利用例: withArgs ["build"] main 第1引数にコマンド引数をリストで渡してしまえば、良いようです。

no_picture

Active Supportの日付演算ってなかなか不思議。

昨日の記事がかなり反響がありまして、みなさまありがとうございます。 関連のある記事を書きたくなりますが、とりあえず、変わらず淡々とメモも残していきたいと思います。ゆるりとGithub入門記事も書きたいです。 ActiveSupportが拡張する日付操作はとても便利です。よく使います。でも、ちょっと黒魔術だなぁって思ったことがあったので紹介します。 Rubyでは日付や時刻クラスのインスタンスと数値が演算できます。 今から1ヶ月後の日付が知りたいのであれば、以下のように書けます。 1.month.since # => 2013-03-07 12:51:18 +0900 1.months.since # => 2013-03-07 12:51:18 +0900 複数形でも単数形でも。 特定の日付からでも同様のことがしたい場合は以下のようになります。 DateTime.new(2013).months_since 1 # => Fri, 01 Feb 2013 00:00:00 +0000 DateTime.new(2013) + 1.month # => Fri, 01 Feb 2013 00:00:00 +0000 有名な機能なので、ご存知の方も多いと思います。 別に、一日単位なら month メソッドとか使わなくてもできます。 DateTime.new(2013) + 1 # => Wed, 02 Jan 2013 00:00:00 +0000 DateTime.new(2013) + 1.day # => Wed, 02 Jan 2013 00:00:00 +0000 さて、本題。 monthだけでなくhourやday,secondなどもありますが、戻り値の型はすべてFixnumになっています。 1 などの数値もFixnumです。 Rubyで日付や時刻を表わすクラスは DateTime, Date, Time などありますが、演算をした場合は、レシーバによって変化します。 でも、monthやsecond メソッドを利用してから演算すると引数によって動作が変化します。どれも足すのはFixnumなのに。 というわけで、サンプルコード。 require 'active_support/all' datetime = DateTime.new 2013, 2, 7 date = Date.new 2013, 2, 7 time = Time.new 2013, 2, 7 datetime # => Thu, 07 Feb 2013 00:00:00 +0000 date # => Thu, 07 Feb 2013 time # => 2013-02-07 00:00:00 +0900 # レシーバによって動作が変わる (1) # 1日先に datetime + 1 # => Fri, 08 Feb 2013 00:00:00 +0000 # 1日先に date + 1 # => Fri, 08 Feb 2013 # 1秒先に time + 1 # => 2013-02-07 00:00:01 +0900 # これを防ぐには和をとるものを明示する (2) datetime + 1.days # => Fri, 08 Feb 2013 00:00:00 +0000 date + 1.days # => Fri, 08 Feb 2013 time + 1.days # => 2013-02-08 00:00:00 +0900 # 秒の場合 (3) datetime + 1.second # => Thu, 07 Feb 2013 00:00:01 +0000 date + 1.second # => 2013-02-07 00:00:01 +0900 time + 1.second # => 2013-02-07 00:00:01 +0900 # Class は どれも Fixnum なのです 1 # => 1 1.class # => Fixnum 1.days # => 1 day 1.days.class # => Fixnum 1.second # => 1 second 1.second.class # => Fixnum # (1) の場合のみレシーバによって動作が変化。動作的には自然だと思う。 # (2), (3) の場合は 引数に応じた動作に。 Dateは演算の結果、型が変化する。 # 使う分には使いやすい。 いいたいことはソースコードにもかいた!