[Ruby] [:name, :yomi] から {:name=>"maiha", :yomi=>"maiha"} を作りたい

最初に思いついたのは、inject

array = [:name, :yomi]
array.inject({}){|h,i| h[i] = "maiha"; h}
=> {:name=>"maiha", :yomi=>"maiha"}

"; h" が冗長で悔しいのよね。

injectでもこんな感じに書けばシンプルにできますよ。

   1  >> [:name, :yomi].inject({}){|h,k| h.merge(k => "maiha")}
   2  => {:name=>"maiha", :yomi=>"maiha"}

Hashinjectmergeと相性がいい。

posted by Png genki on Sun 27 Jan 2008 at 06:45

ActiveSupportでは、メソッドの途中で戻り値を指定するための returningというメソッドがObjectクラスに定義されています。 これを使うと、以下のようにメソッドの最後の式の値が何になるかを 気にせずに記述することができます。

   1  def foo
   2    returning Article.find(parmas[:id]) do |article|
   3      article.foo = 'bar'
   4      article.save
   5    end
   6  end

これと同様のことを、Rubyにあらかじめ用意されているensure を使っても実現可能です。

   1  def foo
   2    article = Article.find(params[:id])
   3  ensure
   4    article.foo = 'bar'
   5    article.save
   6  end

ブロックの値がensureの値を無視する事を利用しています。

posted by Png genki on Sat 26 Jan 2008 at 20:13

rttool 1.0.2.0のgem installに失敗して困ったので記事にしてみます。

RTtoolとは

RTtoolはシンプルな作表ツール。
http://www.rubyist.net/~rubikitch/computer/rttool/

gem installで失敗

   1  gem install rttool
   2  ERROR:  While executing gem ... (Errno::ENOENT)
   3      No such file or directory - /usr/local/bin/rt/rdrt2

ぐぐってルビ吉さんのサイトで解決

下記で解決。tar.gzファイルを落としてインストールすればOKです。
http://www.rubyist.net/~rubikitch/computer/rttool/#3

   1  wget http://www.rubyist.net/~rubikitch/archive/rttool-1.0.2.tar.gz
   2  tar xzvf rttool-1.0.2.tar.gz
   3  cd rttool-1.0.2
   4  ruby setup.rb config
   5  ruby setup.rb setup
   6  ruby setup.rb install

posted by Png satoko on Fri 25 Jan 2008 at 17:26

RubyでバイナリデータをBase64エンコードする場合、 require 'base64'をしてからBase64.encode64(binary)をするか、 以下のようにpackmテンプレートを使うことができます。

   1  [binary].pack('m') #=> Base64 encoded string

しかし、アップロードしたファイル用のテンポラリなファイル名 などに使用する場合、Base64でエンコードした文字列は ファイル名に使えない(可能性が高い)文字を含んでいるため、 そのような場合にはbase64url形式でエンコードします。

base64url って何?

base64url とは、base64 を基に RFC4648 で規定された変換方式で、url とファイル名に使用しても安全になるように設計されています。変更点は、base64 では + と / が使用されていますが、それを - と _ を使用するようにします。具体的には、base64では「ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/」の表で変換しますが、base64url では「ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_」を使用します。

ということで、通常のBase64エンコードした結果に対して、 +-に、/_に置き換えればいいだけなので、 以下のようにすればOKです。

   1  [binary].pack('m').tr('+/', '-_')

posted by Png genki on Thu 24 Jan 2008 at 06:02

annotate_models は、テーブルの情報をModelとFixtureのファイルに コメントとして書き込んでくれる非常に便利なプラグインです。

永く愛用しているプラグインの一つなのですが、 しばらくメンテナンスされていないようなので、 欲しいと思っていたindexに関する情報も出力するようにしてみました。

http://svn.s21g.com/public/rails/plugins/annotate_models_with_index/

こんな感じに、インデックス情報をカラムごとに付加します。

   1  # == Schema Information
   2  # Schema version: 48
   3  #
   4  # Table name: users
   5  #
   6  #  id           :integer(11)   not null, primary key
   7     (* snip *)
   8  #  mobile_email :string(255)   index_users_on_mobile_email(unique)

posted by Png genki on Thu 24 Jan 2008 at 01:09

あすなろとのダブルポストです。

仕事で使ってみたところ、とても簡単にそしてかっこいいグラフが表示できたので紹介します。配置ディレクトリがRoR前提になっていますが、適宜自分の環境に合うように変更してください。
enjoy! ;)

Open Flash Chartサイト

GNU General Public Licenseで公開されています。
http://teethgrinder.co.uk/open-flash-chart/index.php

目標

GoogleFinanceのようなかっちょいいグラフをFlashで表示(下記はキャプチャ画像)
chart
http://finance.google.com/finance?q=google

ダウンロード&解凍

ダウンロードして適当なところに解凍します。
http://teethgrinder.co.uk/open-flash-chart/download.php

ファイルのコピー

解凍したディレクトリ直下のopen-flash-chart.swfと、js/swfobject.jsの2つを下記にコピーします

  • public/open-flash-chart.swf
  • public/javascripts/swfobject.js

viewまたはhtmlを編集します

   1    <% stats[:posts] = [23,44,35,46,78,7] %>
   2  
   3    <%= javascript_include_tag 'swfobject' %>
   4    <div id="chart"></div>
   5    <script type="text/javascript">
   6      var so = new SWFObject("/open-flash-chart.swf", "ofc", "180", "100", "9", "#FFFFFF");
   7      so.addVariable("variables","true");
   8      so.addVariable("y_label_style", 'none');
   9      so.addVariable("x_label_style", "10,#799191,0,2"); //22メモリごとにラベル表示の意。
  10      so.addVariable("x_axis_steps","1"); //メモリ軸
  11      so.addVariable("y_ticks","5,10,2");
  12      so.addVariable("y_min","<%= stats[:posts].min %>"); //最小値
  13      so.addVariable("y_max","<%= stats[:posts].max %>"); //最大値
  14      so.addVariable("x_labels","Mon,Tue,Wed,Thurs,Fri,Sat,Sun"); //x軸ラベル
  15      so.addVariable("values", "<%= stats[:posts].join(',') %>"); //  16      so.addVariable("line_hollow", "3,#799191,This week,10,5"); //グラフの種類
  17      so.addVariable("bg_colour", "#F0F0F0");
  18      so.addVariable("x_axis_colour", "#FFFFFF");
  19      so.addVariable("x_grid_colour", "#FFFFFF");
  20      so.addVariable("y_axis_colour", "#FFFFFF");
  21      so.addVariable("y_grid_colour", "#FFFFFF");
  22      so.addVariable("tool_tip","#x_label#:#val#");
  23  
  24      so.addParam("allowScriptAccess", "sameDomain");
  25      so.write("chart");
  26    </script>

posted by Png satoko on Wed 23 Jan 2008 at 10:41

irbを使っているときに、オブジェクトにどんなメソッドが 定義されているのかをpublic_methodsなどで調べることが 出来ますが、たいていの場合大量のメソッドがリストアップされて わかりにくくなってしまいます。

今回は、そんなときに良くやる方法を紹介します。

   1  >> Time.public_methods.sort - Object.public_methods
   2  => ["_load", "at", "days_in_month", "gm", "httpdate", "iso8601", "local", "local_time", "mktime", "now", "parse", "rfc2822", "rfc822", "time_with_datetime_fallback", "times", "today", "utc", "utc_time", "xmlschema", "yaml_new", "zone_offset"]

public_methodsからObjectpublic_methodsを取り除いたものを 表示しています。Objectの代わりに適当な親クラスを指定することで、 クラス階層の特定の領域で定義されたメソッドを表示することも できますね。

posted by Png genki on Mon 21 Jan 2008 at 14:14

Now, we are working on ShootingStar-4.0.0

It will be working on Windows by using WaitForMultipleObject API. I loved it since more than 10 years ago and thought it as is one of a beautiful aspect of Windows.

It may be shipped on next month.

posted by Png genki on Mon 21 Jan 2008 at 06:46

Rails勉強会@東京#26

Genki Takiuchi

Recent Situation:

  • Founded a small company.
    • And it has already survived 3 months, Yay!
  • Shipped ShootingStar 3.2.6
  • Jogging and swimming.
  • Finally I bought e-mobile (D02HW)
  • And also being with Rails 2.0.2

Favorite Things:

  • C/C++ Template, JavaScript, Ruby.
  • Thinking algorithm, Rendering (CG) and 3D.
  • Vim7, Zsh, GNU screen, rails.vim, ZenTest.

Thank you!

posted by Png genki on Sun 20 Jan 2008 at 14:33

以前紹介した Hash#only にちょっとした修正。

lib/hash_ext.rb

   1  class Hash
   2    def only(*args)
   3      args = *args if args[0].is_a? Array
   4      args.inject({}){|hash, key| hash[key] = self[key] if include? key; hash}
   5    end
   6  
   7    def only!(*args)
   8      args = *args if args[0].is_a? Array
   9      args.inject({}){|hash, key| hash[key] = self[key]; hash}
  10    end

以前のHash#onlyは、指定したキーが存在しない場合でも

   1  {:foo => 1}.only(:bar) #=> {:bar => nil}

というように、nilを指すHashを返していましたが、 キーが存在しない場合に空のHashを返すようにしてみました。 従来の挙動をするメソッドは、Hash#only!と感嘆符付きの メソッドにしています。 修正後の挙動は以下の通り。

   1  {:foo => 1}.only(:bar) #=> {}
   2  {:foo => 1}.only!(:bar) #=> {:bar => nil}

posted by Png genki on Sat 19 Jan 2008 at 13:30