細かい点ですが、メールアドレスの登録をアドレスブックから行えるようにしました。

絵文字キーボードの利用が出来なくなる可能性があるようなので("Apple issues App Store-wide Emoji take-down order")、
独自に絵文字の文字コードを入力するためのキーボードを用意する事を考えています。
次のアップグレードでは、祝日の詳細を表示する機能の実装を予定していましたが、緊急性から、絵文字キーボードの実装が完了した時点でアップデート申請を行うかもしれません。

posted by genki genki on Fri 27 Feb 2009 at 20:27 with 0 comments

MerbでExpiresやCache-Controlを設定する場合、
アクションメソッドの中で、以下のようにすれば良いようです。

ruby>>
headers['Cache-Control'] = 'public'
headers['Expires'] = 3.days.from_now.utc.rfc2822
<<--

posted by genki genki on Thu 26 Feb 2009 at 18:40 with 0 comments

Merbでリソースに:editのようなカスタムアクションを追加する場合、
以下のように:memberオプションを利用出来ます。

config/router.rb

ruby>>
resources :materials, :member => {:download => :get}
<<--

これによって、GET /materials/:id/downloadが、Materials#downloadにmapされます。

posted by genki genki on Thu 26 Feb 2009 at 01:21 with 0 comments

Merbでファイルアップロードのspecを書く場合には、
multipart_***系のAPIを利用出来ます。
以下は一例です。

ruby>>
tmp = Tempfile.new('spec')
path = tmp.path + ".txt"
begin
file = open(path, "w+")
file.write "test"
multipart_post(resource(:materials),
:material => {:id => nil, :label => 'test', :file => file})
tmp.close
ensure
file.close
File.unlink path
end
<<--

:content_typeはfilenameから推定されるので、拡張子をくっつけています。

posted by genki genki on Wed 25 Feb 2009 at 22:44 with 0 comments

Merbのデフォルト構成にはRailsのような
HTMLのsanitizeを行うようなヘルパーメソッドは無いのですが、
Gemで提供されている
sanitize
というライブラリを使うと、簡単にHTMLのsanitizeを行う事が出来ます。

ruby>>
Sanitize.clean(html, Sanitize::Config::RELAXED)
<<--

タグ毎に有効・無効の細かい設定が出来て、使い勝手が良いです。

posted by genki genki on Tue 24 Feb 2009 at 15:19 with 0 comments

Singleton Methodを削除する方法
についてですが、
Objectクラスに用意されているとありがたいですね。

object_ext.rb

ruby>>
class Object
def remove_singleton_method(*args)
(class << self; self end).class_eval do
args.each{|i| send :remove_method, i}
end
end
end
<<--

こんな感じ。

posted by genki genki on Mon 23 Feb 2009 at 21:55 with 0 comments

方法を探していたのですが、意外と苦戦したのでメモ。

ruby>>
object = new Object
def object.foo; end
object.singleton_methods #=> [:foo]
(class << object; self end).class_eval{send :remove_method, :foo}
object.singleton_methods #=> []
<<--

これで行けるようです。instance_eval{undef foo}でも削除はできますが、その場合親クラスのメソッドにもアクセス出来なくなってしまうので、
singleton methodだけを削除する場合には、
メタクラスのインスタンスメソッドをremove_methodするのが良いようです。

posted by genki genki on Mon 23 Feb 2009 at 21:25 with 0 comments

MerbのCacheはなかなか優れた設計なので面白いのですが、
開発中にログにCache Miss/Hitの具合が分かるように出力してほしかったので、
development環境用のLoggingMemcachedStoreというのを書いてみました。

ruby>>
class LoggingMemcachedStore < Merb::Cache::MemcachedStore
include Extlib::Hook

before :read do |key, params|
if exists?(key, params)
Merb.logger.debug "Cache Hit: #{key}"
else
Merb.logger.debug "Cache Miss: #{key}"
end
end

before :write do |key, data, params, conds|
Merb.logger.debug "Cache Write: #{key}"
end
end
<<--

こんな感じでログに出ます。

pre>>
merb : worker (port 4000) ~ Cache Hit: Plugins#show
merb : worker (port 4000) ~ Cache Write: Plugins#show
<<--

posted by genki genki on Sat 21 Feb 2009 at 01:19 with 0 comments

EC2のサーバ上でruby-1.8.x系で動作しているpassenger(aka mod_rails)
と平行して、ruby-1.9.1を動かす環境を用意するために色々と試行錯誤を繰り返していたのですが、ひとまず良さそうな構成に落ち着いたのでメモしておきます。

構成

入り口から順に並べるとこんな感じです。

  • apache2 (:80)
  • mod_proxy_balancer (:80 -> :4000)
  • swiftiply (:4000 <- :30000)
  • merb cluster with SwiftipliedMongrel adapter (:30000)

apache2はpassengerを使っているので外せないとして、
ruby-1.9.1で動かすサービスはmod_proxy_balancerを使う事にしました。
最初はバックエンドに直接merb clusterを当てていたのですが、
現状のmerb clusterにはgraceful reloadする機能が無いようだったので、
間になにか挟む事にしました。

そこで、以前から目を付けていた
Swiftiply
を試す事にしました。
Swiftiplyはとても面白い設計のウェブサーバで、そのへんは
rakutoさんの記事
[Rails] Swiftiplyのアーキテクチャとベンチマーク
を読むのがわかりやすいでしょう。

merbはbuilt-inでSwiftiply用のアダプター(SwiftipliedMongrel adapter)を備えているので、Swiftiplyを起動する設定をおこなえば、使うのはわりと簡単です。

しかし、例によってswiftiplyが依存しているeventmachineがruby-1.9.1
でインストール出来なかったので、原因を調査。
単純にテストの実行だけがうまく動いてないようだったので、テスト無しでインストールしました。

あとは、swiftiplyの起動スクリプトを用意。

/etc/init.d/swiftiply

ruby>>
#!/usr/bin/env ruby

PID = "/var/run/swiftiply.pid"

case ARGV[0]
when 'start'
if File.exist?(PID)
puts "swiftiply is already started."
exit 1
end
print "Starting swiftiply: "
pid = fork do
Process.setsid
Process.exec "swiftiply", "-c", "/etc/swiftiply.yml"
end
begin
open(PID, "w"){|file| file.write pid}
puts "done"
rescue Exception => e
puts e.message
Process.kill 9, pid
end
when 'stop'
print "Stopping swiftiply: "
begin
pid = open(PID).read.to_i
File.unlink PID
Process.kill 9, pid
puts "done"
rescue Exception => e
puts e.message
end
when 'restart'
system $0, 'stop'
system $0, 'start'
else
puts "usage: {start|stop|restart}"
end
<<--

アプリケーションの起動、停止は以下のようにおこないます。

pre>>
cd #{current_path}; #{merb} -K all
cd #{current_path}; #{merb} -e production -a swift -c 1 -p 30000
<<--

これで動きますが、プロセスが死んだりすると不安なので、
monitを使って死活管理をおこなうようにします。

/etc/monit/monitrc

pre>>
check process swiftiply
with pidfile /var/run/swiftiply.pid
group root
start program = "/etc/init.d/swiftiply start"
stop program = "/etc/init.d/swiftiply stop"
if failed port 4000 then restart
if 5 restarts within 5 cycles then timeout

check process merbist
with pidfile /mnt/app/merbist/current/log/merb.30000.pid
group root
start program = "/mnt/app/merbist/shared/script/start"
as uid app and gid app
stop program = "/mnt/app/merbist/shared/script/stop"
as uid app and gid app
if failed port 30000 then restart
if 5 restarts within 5 cycles then timeout
depends on swiftiply
<<--

以上で完了。

現在、http://merbi.st/ は上記の設定で動いています。

See Aslo

追記

しばらく運用してみたのですが、プロセスが数時間に一回ぐらいのペースで落ちる問題があったので、Swiftiplyの代わりにPoundを使う構成に変えました。
Swiftiplyは次のバージョン0.7.0から、クラスタリングのサポートが強化されるようなので、それまで待ってみた方が良いかもしれないですね。

posted by genki genki on Fri 20 Feb 2009 at 16:05 with 0 comments

Ruby-1.9.1を使うと、
以下のようにして簡単にRubyVMのInstaractionSequenceを見る事が出来ます。

ruby>>

puts RubyVM::InstructionSequence.new("puts 'Hello, world!'").disasm #=> nil
== disasm: <RubyVM::InstructionSequence:@>==========
0000 trace 1 ( 1)
0002 putnil
0003 putstring "Hello, world!"
0005 send :puts, 1, nil, 8,
0011 leave
<<--

生成したInstractionSequence(aka iseq)は、evalメソッドを呼び出して実行する事もできます。

ruby>>

RubyVM::InstructionSequence.new("puts 'Hello, world!'").eval #=> nil
Hello, world!
<<--

さらに、to_aメソッドで個々のインストラクションに分解する事も出来ます。

ruby>>

RubyVM::InstructionSequence.new("puts 'Hello, world!'").to_a
["YARVInstructionSequence/SimpleDataFormat", 1, 1, 1, {:arg_size=>0, :local_size=>1, :stack_max=>2}, "", "", :top, [], 0, [], [1, [:trace, 1], [:putnil], [:putstring, "Hello, world!"], [:send, :puts, 1, nil, 8, nil], [:leave]]]
<<--

posted by genki genki on Fri 20 Feb 2009 at 01:38 with 0 comments

以前要望があった気がしたので、
PokéDia-1.2のアップデート
を記念して、
MacOSXのSafariで自動的に選択した文字列をコピーするSIMBLプラグイン
SafariCopyOnSelect
を作ってみました。

SafariCopyOnSelect.bundle.zip

インストール方法

  1. まずはSIMBL
    をインストールします
  2. 上述のSafariCopyOnSelect.bundle.zipファイルをダウンロードして展開します
  3. 展開されたSafariCopyOnSelect.bundleを、
    ~/Library/Application Support/SIMBL/Plugins/の下にコピーします。
    ディレクトリが無い場合は作成してください。
  4. Safariのプロセスを終了し、Safariをもう一度起動します

これでOKです。
一時的にこの機能をオフにする場合は、
以下のようにメニューから「Copy On Select」をオフにしてください。

ss01

オンに戻せば再び有効化されます。

posted by genki genki on Thu 19 Feb 2009 at 18:30 with 0 comments

長らくお待たせしておりました、PokéDiaのバージョン1.2が、
iTunesストアからアップデート可能になりました。

ss

PokéDia-1.2 (iTunes Store)

PokéDia-1.2では、重要なバグ(稀にメモが消える、メモの表示が乱れる事がある)の修正と、一覧表示機能、検索機能の実装を行いました。日本語でお使いのiPhoneでは絵文字を使うことも出来ます。

今後とも、頂いているご要望をもとに、さらなる機能改善をおこなって参りますので、ご愛顧のほどをお願いいたします。

See Also

posted by genki genki on Thu 19 Feb 2009 at 12:14 with 0 comments

thinを使ってmerbアプリケーションをrackupする方法のメモです。
以下のようなconfig.ruファイルを用意します。

ruby>>

config.ru

require 'rubygems'
require 'merb-core'Merb::Config.setup(
:merb_root => File.expand_path(File.dirname(FILE)),
:environment => ENV['RACK_ENV'])
Merb.environment = Merb::Config[:environment]
Merb.root = Merb::Config[:merb_root]
Merb::BootLoader.run

use Merb::Rack::Static, Merb.dir_for(:public)
run Merb::Rack::Application.new
<<--

あとは、以下のようなコマンドで起動します。

pre>>
% RACK_ENV=development thin -R config.ru start
<<--

posted by genki genki on Thu 19 Feb 2009 at 02:47 with 0 comments

pre>>
% git pull
<<--
は、
pre>>
% git fetch
% git merge /
<<--
と同じ事です。

git pull --rebaseというのもよく見かけますが、これは
pre>>
% git fetch
% git rebase /
<<--
と同じ事です。mergeの代わりにrebaseを使います。

See Also

posted by genki genki on Thu 19 Feb 2009 at 01:06 with 0 comments

githubなどを使っていると、簡単にリポジトリをフォーク出来るので、
有名なプロジェクトになると、数十のリポジトリが並走している事もしばしばです。
多くの場合、フォークのツリーをたどっていけば、ルートになるリポジトリが見つかるのですが、ルートになっているプロジェクトのコードが最新であるとは限りません。
フォークしたリポジトリの方にバグの修正が入っていたり、パッチがあたっていたりする事も良くあります。

そのような場合には、
pre>>
% git remote add
<<--
のようにして、関心のあるremoteリポジトリを登録しておきます。
登録が済めば、
pre>>
% git fetch
<<--
でリモートのブランチを手元に持ってくる事が出来ます。
例えば手元のmasterとリモートのmasterの差異を知りたければ、

pre>>
% git diff master../master
<<--

のようにする事で調べられます。

posted by genki genki on Thu 19 Feb 2009 at 00:51 with 0 comments

Merbはコマンドラインから-c 3のように指定する事で、
クラスターとして起動出来ますが、これを設定ファイルの
中から行う場合には、以下のように書けば良いようです。

config/init.rb
ruby>>
Merb::Config.use do |c|
...
 c[:port] = 4001
 c[:cluster] = 2
end
<<--

あとは、普通にmerbコマンドで起動するだけです。
config/environments/production.rbなどで設定しても良いですね。

posted by genki genki on Tue 17 Feb 2009 at 01:02 with 0 comments

今月もRails勉強会
に行ってきました。

Merbのセッションをやる予定でしたが、1.9.1対応の話とネタが被ったのでマージしました。

  • ruby-1.9.1で、merbのspecが通らなくなった
    • そもそもrspecがまだruby-1.9.1に対応してない
    • ubuntuだとGemでインストールしたコマンドが実行出来ない
      • ruby-1.9.1のバグ?

ということで、会場ででてきた修正案
ruby>>
static int
file_load_ok(const char *path)
{
   return eaccess(path, R_OK) == 0 && rb_file_file_p(Qnil, rb_str_new2(path));
}
<<--

eaccessでチェックしてるだけだったので、環境によっては
ディレクトリをloadしようとしてエラーが発生してしまうようです。
この問題が発生する典型的な例としては、

pre>>
lib/foo/
bin/foo
<<--

というようなディレクトリ階層にある場合に、load "foo"を行う場合が挙げられます。
結構深刻な問題だと思うので、早いうちに修正版のruby-1.9.1がリリースされると良いです。

懇親会ではCOBOLの話をしてました。
メタコボラーの時代がくる!?

posted by genki genki on Mon 16 Feb 2009 at 14:09 with 0 comments

ちまたで話題のCanonical URLですが、既存のRailsアプリケーションを
Canonical URLに対応させるためのプラグインを紹介します。

config/environment.rbの中で、以下の行を追加します。

ruby>>
config.gem 'mbleigh-canonical-url',
:lib => 'canonical_url',
:source => 'http://gems.github.com'
<<--

続いて、sudo rake gems:install
でGemをインストールします。
次に、ViewのHEADの中に以下の一行を追加します。

html>>
<%= canonical_link_tag %>
<<--

最後に、Controllerのshowアクションの中で、
respond_toやrenderの呼び出しより上に以下の一行を追加します。

ruby>>
canonical_url article_path(@article)
<<--

これはarticlesというリソースの例ですが、
実際のアプリケーションで使っているリソース名に置き換えてください。

これで完了。
Slagを使っていたりする場合に、Permalinkをcanonical urlとして指定したりするのが典型的な使い方になるのかな。

See Also

posted by genki genki on Sat 14 Feb 2009 at 22:40 with 0 comments

gemファイルはRubyのライブラリ配布用のアーカイブ的なファイル形式ですが、
今回はこれを展開して中身を取り出す方法を紹介します。

まずは、適当なgemファイルを用意して、tarコマンドで展開します。

pre>>
% tar xvf foo.gem
% ls
data.tar.gz metadata.gz
<<--

このように、data.tar.gzとmetadata.gzという二つのファイルが出てきます。

続いて、data.tar.gzを展開すると、gemspecファイルに記載されている
ファイル群一式が展開されます。

pre>>
% tar data.tar.gz
<<--

metadata.gzは、gzipで圧縮されたYAML形式のgemspecです。

追記

gemファイルを展開する方法としては、gem unpackという専用のコマンドがあるようです。見落としていた。

posted by genki genki on Sat 14 Feb 2009 at 16:31 with 2 comments

Ruby-1.9.1がリリースされて以来、
@maiha
さんと一緒にMerbのRuby-1.9.1対応のための作業を続けてきましたが、
ようやくMerbアプリケーションをRuby-1.9.1で動かす事ができました。

ss
http://merbi.st

決定的に重要だったのは、@ko1_twitterさんが作ってくれた
methoparaです。
これによって、merbが抱えていたmerb-action-argsに関する問題を解決するための道が開かれ、Ruby-1.9.1対応を行うためのモチベーションが高まりました。

今回のRuby-1.9.1対応のために作ったパッチや、修正版のGemなどの多くは
github上に残っています
(http://github.com/maiha, http://github.com/genki)
残りは、http://merbi.st/pluginsで公開されています。

Good luck!

posted by genki genki on Sat 14 Feb 2009 at 14:47 with 0 comments

先週申請していたPokéDia-1.2のアップデート申請ですが、
再申請が必要となってしまったので、問題を解決して再度申請いたしました。

今回の問題解決の過程で生じた副産物として、
Bookナビゲーション用のUIToolbarアイコンを提供いたします。

book.png

たいしたものではないので、役立つようであればご自由にお使いください。

おそらく、もう数日お待たせする事になってしまい、申し訳ありません。

See Also

posted by genki genki on Sat 14 Feb 2009 at 13:39 with 0 comments

irb_rocketがRuby-1.9.1で動かないよ、というコメントを頂いたので、
ruby-terminfoをRuby-1.9.1対応にしてみました。

これでirb_rocketをRuby-1.9.1で使う事が出来ます。

pre>>
% sudo gem install irb_rocket --source http://merbi.st
<<--

posted by genki genki on Fri 13 Feb 2009 at 16:16 with 0 comments

@maiha
さんがRuby-1.9.1でMongrelをインストールできるようにしてくれました。
修正したバージョンは、以下のコマンドでインストール出来ます。

pre>>
% sudo gem install mongrel --source http://merbi.st
<<--

不要になったと思われるfastthread関係のgemへの依存を切っています。

それにしても、Mongrelってメンテナンスされてるのかな。
結構メンテナンスされてるのかどうなのかわからないGemがあって悩みどころですね。

posted by genki genki on Fri 13 Feb 2009 at 10:03 with 0 comments

RubyGemsをインストールする時に、--source
オプションによってgemリポジトリを指定する事が出来ますが、
これを指定した場合、そのGemが依存するGemも同じsourceから取ってこようとするため、
依存するGem一式を全てそのgemリポジトリ上に用意する必要があります。

これはなかなか大変なので、--source指定した場合には、
指定した場所に無い場合、システムに設定されているデフォルトのgemリポジトリに探しにいってくれるとありがたいですね。

posted by genki genki on Fri 13 Feb 2009 at 09:21 with 0 comments
iPhone開発者座談会

出席いただいた皆様、ありがとうございました。
皆様の今後の開発の一助となれば幸いです。
当日高橋さんが紹介してくれた資料の一部を置いておきます。

http://www.slideshare.net/takiuchi/devsami09-takiuchi

座談会の内容とは関係ないですが、
控え室からステージに移動するまでの経路が、もろに厨房の中を通過する感じだったのが面白かったです。

posted by genki genki on Fri 13 Feb 2009 at 09:01 with 0 comments

Yesterday (Feb 10, 2009),
asakusa.rb
took place at Akihabara, Tokyo.
asakusa.rb is a rubyist community that is based on Asakusa.

In the monthly meet-up of that community,
@ko1_twitter wrote a code snippet.
This snippet is a kind of backport of Method#parameters for Ruby-1.9.1.
His quick job led a way for merbists to change merb to be corresponding to Ruby-1.9.1.
He named his work "methopara". It stands for METHOd PARAmeters.

And I made it as a gem
for ease of use.
Now we can use it by the command below.

pre>>
% sudo gem install methopara --source http://merbi.st
<<--

Usage is as follows.

ruby>>

require "rubygems"
require "methopara"
def foo(a,b=nil,&c) end
method(:foo).parameters
=> [[:req, :a], [:opt, :b], [:block, :c]]
<<--

This gem is only for Ruby-1.9.1.
Because Ruby18x have merb-action-args, and Ruby-1.9.2 and its successors will have built-in Method#parameters.

Enjoy!

See Also

posted by genki genki on Wed 11 Feb 2009 at 10:04 with 1 comment
posted by genki genki on Mon 9 Feb 2009 at 11:05 with 0 comments

GitHubでGemを公開する場合に、バージョン管理をどうするか色々考えていたのですが、良さそうな方法を見つけたのでメモしておきます。

  • 開発時のバージョン番号はリリースしているものより一つ進める
    • 0.1.0をリリースしてる場合、ソースコード中のバージョン番号は、次のリリースバージョン(例えば0.1.1など)にしておく
  • リリース時にgemspecを更新してpushする

これによって、http://gems.github.com をリリースGemリポジトリとして使う事が出来ます。

また、開発中のEdgeGemを配布する場所としては、自分でGemリポジトリを作ってしまうのが良さそうです。
弊社では、http://merbi.st というEdgeGemリポジトリを用意しています。
これは、あらかじめ登録してあるGitHubなどの外部リポジトリから、定期的に最新のコードをfetchしてGem化しています。

posted by genki genki on Mon 9 Feb 2009 at 08:57 with 0 comments

名もないベンチャーが億単位の案件を獲るには (Re: 真のソフトウェア工学はもう存在している)

ただ500億円ほどのプロジェクトであれば、そのすべての金額を1社に任せるのではなく、保険のために金額の1割を小さいベンチャー企業に任せるというのはありだと思うんですけど、どうでしょうか。どんなに大手でも失敗するときは失敗するから、無名だが優秀そうなベンチャーにも同時に案件を任せてみるというのは、リスクを回避するという観点から十分にありだと思います。

イメージ的には、自動車保険の代車費用担保特約みたいな感じですね。

実績があるが高コストな方法が主流を占めている状況で、実績は無いが低コストな方法を売り込んでいく手法というのは、過去の歴史の中に色々と成功例があるはずなので、調べてみたいですね。

posted by genki genki on Sun 8 Feb 2009 at 20:25 with 0 comments

irbはインタラクティブにrubyのコードを実行出来る
非常に便利なユーティリティですが、
脳内にある「irbのあるべき姿」と比べると、
ちょっとだけ足りないところがあると思っていました。

そこで、思い通りの動きをするようにirbをカスタマイズする
irbプラグイン
irb_rocket
を作ってみました。
これを使うと、いつも見慣れたirbが、こんな風になります。

ss

  • inputの末尾に#=>に続いて結果が表示されます
  • 結果はWirbleを使って色づけしています
  • 標準エラー出力への出力は赤で表示します

インストール方法

irb_rocketは
wirble

ruby-terminfo
に依存しているので、
それらをインストールします。
続いて、以下のようにhttp://merbi.stからgemをインストールします。

pre>>
% sudo gem install irb_rocket --source http://merbi.st
<<--

最後に、~/.irbrcに、以下のコードを加えます。

ruby>>
require 'rubygems'
require 'irb_rocket'
<<--

あとは、いつものようにirbを起動するだけです。

追記

ruby-terminfoはakrさん作のterminfoのruby用バインディングです。
インストールが大変だったので、gem化してこちらに置いておきました。

以下のようにインストール出来ます。
pre>>
% sudo gem install ruby-terminfo --source http://merbi.st
<<--

posted by genki genki on Sun 8 Feb 2009 at 16:53 with 4 comments
前回のアップデートから間があいてしまいましたが、 iPhone用の手帳アプリ、[PokéDia-1.2](http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=298763195&mt=8) のアップデート申請をいたしました。 iPhone シミュレータ iPhone シミュレータ 今回のアップデート内容は以下の通りです。 * メモが消えるバグを修正 * メモの表示が乱れる問題を修正 * 絵文字キーボードへの対応(左図参照) * メモの一覧表示機能(右図参照) * メモの検索機能(右図参照) 絵文字キーボードについては、 [Tweeter](http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=298729529&mt=8) に習って日本のiPhoneのみ対応となっています。 今日の出来事を表示する機能については、次回のアップデートで追加予定です。今後ともよろしくお願いいたします。 審査が無事に通過する事を祈りつつ。 **See Also** * [PokéDia ¥350 (iTunes Store)](http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=298763195&mt=8)
posted by genki genki on Sat 7 Feb 2009 at 13:56 with 0 comments

Ruby-1.9.1では、以下のように配列リテラルの中でHashを定義する事が出来るようになったのですね。

ruby>>
[:foo, :bar => :baz]
#=> [:foo, {:bar=>:baz}]
<<--

いままでも、

ruby>>
[:foo => :bar]
<<--

のような形式であればOKだったのですが、配列リテラルの中に
Hash以外の要素を含む場合には構文エラーが発生していました。

posted by genki genki on Fri 6 Feb 2009 at 18:10 with 0 comments

従来のソフトウェア工学が決定的に間違っている点

従来のソフトウェア工学が決定的に間違っている点は、
ソフトウェアを作るソフトウェアに関する工学ではない事だと思う。

100倍の生産性を達成するためには、ひとつ階段を上にのぼる必要がある。

従来のソフトウェアエンジニア人事工学が決定的に間違っている点

「やらなきゃいけない」仕事が20%で、残りの80%が「やりたいしごと」。たとえ単純作業でも、残り80%にそれが属しているのであれば嬉々としてやってしまう。彼らからこれを取り上げてしまうと、残り20%も小さくなってしまう。好きなようにやらせておくのが吉である。

つまらないコードを生成するコードを書く事は、
つまらないコードを書く事自体と比べて何倍も面白い。

手でコードを書くプログラマと、コードにコードを書かせるメタプログラマでは、
規模が大きな仕事になるほど差が開いていくと思う。

「ソフトウェア工学」は矛盾語法か?

真のソフトウェア工学はまだ未来のものだ。一年とかけずに三千人以下でエンパイアステートビルを造り上げるようなものは、現在のソフトウェア工学に存在しない。(中略) 何十万もの奴隷を何十年も使い石に石を重ねてゆく様は、まさに今日ほとんどのソフトウェア開発で行われている事だ。

真のソフトウェア工学は、もう存在している。それは、
タワークレーンを使った高層ビル建築
に似ている。
メタプログラマーの仕事は、タワークレーンを組み立てるために小さなクレーンを動かす事だ。
それを実現するための道具はもう揃っていると思う。
それを使いこなしてる人もそれなりにいる。
では何が足りないのだろうか。

tc

それはなんと言っても、実績が足りない。というか無い。
例えば5人のメタプログラマーの会社が、500億円の案件を50億円で受注したというような事例は皆無だと思う。
経営者は、万が一プロジェクトが失敗に終わった時に、実績が無い事に手を出した事を責められる事になる。
しかしながら、これについては成功事例が生まれれば改善する可能性があると思う。
営利企業の経営者が、これほどの節約機会を見過ごすとは思えない。

という事で、システム経費を劇的に圧縮する方法をお探しの方は、

までご相談ください :-)

追記

  • 「真のソフトウェア工学」という名称使ったのは、引用元の「「ソフトウェア工学」は矛盾語法か?」の中で使われている名称をそのまま受けての事です。そういう学問が存在してるよ、という事を言いたかった訳ではないです。
posted by genki genki on Fri 6 Feb 2009 at 08:14 with 0 comments

ss

Yay! I am looking forward to it very much!

Merbはmerb-action-argsが無くても動くのだけど、
あの格好良さを知ってしまうとね・・・。

posted by genki genki on Fri 6 Feb 2009 at 05:57 with 0 comments

merbでGeneratorプラグインを作る方法を紹介します。

merbのgeneratorの仕組みは、
templater
という汎用的なGeneratorフレームワークを使って作られています。
なので、基本的にはtemplaterを使ったGeneratorの作り方という事になります。

まずは、Generatorプラグインのひな形を生成します。

pre>>
% merb-gen plugin hello
<<--

Gemの形で提供されるものであれば、merb-pluginの形式である必要は無いですが、簡単にそれを用意してくれるので、merb-gen pluginを使ってみました。

さて、続いて、GEM_ROOTにGeneratorsというファイルを作ります。

ruby>>
scope 'merb-gen' do
dir = File.join(File.dirname(FILE), 'lib', 'generators/')
Merb.add_generators dir + 'hello_generator'
end
<<--

続いて、GEM_ROOT/lib以下のディレクトリ構成を以下のような感じにします。

pre>>
lib
-- generators |-- hello_generator.rb -- templates
-- hello |-- app | -- app以下のファイル群
-- spec -- spec以下のファイル群
<<--

hello_generator.rbが、Railsのgeneratorで言うところの
Generatorマニフェストファイルに相当します。

以下はmerb-mailerのgeneratorファイルの例です。

ruby>>
module Merb::Generators
class MailerGenerator < NamespacedGenerator

def self.source_root
  File.dirname(__FILE__) / 'templates' / 'mailer'
end

desc <<-DESC
  Generates a mailer
DESC

option :testing_framework, :desc => 'Testing framework to use (one of: rspec, test_unit)'

first_argument :name, :required => true, :desc => "mailer name"

template :mailer do |t|
  t.source = 'app/mailers/%file_name%_mailer.rb'
  t.destination = File.join("app/mailers", base_path, "#{file_name}_mailer.rb")
end

template :notify_on_event do |t|
  t.source = 'app/mailers/views/%file_name%_mailer/notify_on_event.text.erb'
  t.destination = File.join("app/mailers/views", base_path, "#{file_name}_mailer/notify_on_event.text.erb")
end

template :controller_spec, :testing_framework => :rspec do |t|
  t.source = 'spec/mailers/%file_name%_mailer_spec.rb'
  t.destination = File.join("spec/mailers", base_path, "#{file_name}_mailer_spec.rb")
end

end

add :mailer, MailerGenerator
end
<<--

あとは、GemをインストールすればOK.

posted by genki genki on Thu 5 Feb 2009 at 05:39 with 0 comments

Gemをインストールすると、依存するGemも一緒にインストールする事が出来ますが、
Gemの依存関係は、通常の依存関係の他に、開発環境用の依存関係も設定されています。
開発環境用の依存関係は、そのGemの開発や修正を行うために必要なGemを表しています。
今回は、開発環境用の依存関係をまとめてインストールする方法を紹介します。

pre>>
% sudo gem install --development gemname
<<--

これでOK.

posted by genki genki on Wed 4 Feb 2009 at 02:42 with 0 comments

Ruby-1.9.1対応や、1.8.7、1.8.6での動作確認などをする必要がでてきたので、
そんな状況で便利なmultirubyを試してみました。

multirubyはZenTestの一部として公開されているので、
ZenTestが入っていない人はインストールします。

pre>>
% sudo gem install ZenTest
<<--

続いて、以下のような感じでruby-1.8.6 p287をインストールします。

pre>>
% multiruby_setup mri:svn:tag:v1_8_6_287
% multiruby_setup mri:svn:tag:v1_8_7_72
% multiruby_setup mri:svn:tag:v1_9_1_0
<<--

SVNからソースをチェックアウトしてきて、コンパイルが始まります。

終わったら、rubygemsを更新します。

pre>>
% multiruby_setup update:rubygems
<<--

あとは、

pre>>
% multiruby -S irb
<<--

などのようにすると、複数のバージョンのRubyでirbが順番に実行されます。

pre>>
multiruby -S gem install gemname
<<--

のようにして各環境用にGemをインストールします。

See Also

posted by genki genki on Wed 4 Feb 2009 at 02:08 with 0 comments

Proc#to_sourceみたいな強力なリフレクション機能がRubyに実装されて欲しいので、言語デザイナーがエキサイト出来るようなゲームを考えてみる。

  1. クラスオブジェクトの取得
  2. メソッドオブジェクトの取得
  3. メソッドカテゴリ
  4. アノテーション
  5. メソッドの実行時呼び出し(Invocation)
  6. クラスの実行時作成
  7. メソッドの実行時作成
  8. メソッドボディの置き換え(Swizzling)
  9. メソッドシグネチャへのアクセス(#parameters)
  10. ASTへのアクセス(ParseTree)
  11. メソッドソースへのアクセス(to_source)
  12. module/mixinのuninclude, unextend, unmixin
  13. 全ての動的修正を元の状態に戻せる

さらにアドバンスドな項目

  • 実行時修正の安全保障(Sandbox)
  • 実行時修正の権限管理機能
  • 実行時修正の履歴管理機能
posted by genki genki on Tue 3 Feb 2009 at 10:30 with 2 comments

Getting ready for Ruby 1.9.1

We are excited about Ruby 1.9.1. Of course, with all the performance improvements, who wouldn’t be? Unfortunately a large number of Ruby libraries and extensions still don’t work on 1.9.1, so Ruby 1.9 cannot be considered production-ready yet.

しばらくは大きなプロジェクトのRuby-1.9.1対応がにぎやかになりそうですね。
安定板のリリースは重要だな。

Merbはまだaction-argsの問題があるけど、
1.9.1でMethod#parametersが出なかったので、
ParseTreeあたりが1.9.1に対応する感じで進化して対応される気がする。
せめてProc#to_sourceがあればripperを使ってなんとか出来たと思うんだけどなー。

posted by genki genki on Tue 3 Feb 2009 at 10:17 with 0 comments

iPhoneの通話中にHomeに戻ってからアプリケーションを起動すると、
以下のような普段の2倍の高さの緑色のステータスバーが表示された状態で
アプリケーションが立ち上がります。

ss1

高さが2倍になってるので、
通常のステータスバーの場合と比べて、
やや狭い画面にあわせたデザインにする必要があります。
さらに、通話が中断された場合、緑色のステータスバーが消えて、
通常の高さのステータスバーになるのですが、
この時に、[UIApplication application:willChangeStatusBarFrame:]
が呼ばれないという不具合が以下のサイトで報告されていました。

posted by genki genki on Mon 2 Feb 2009 at 04:02 with 0 comments

merbで採用されているジェネレータフレームワークの本命、
templater
に、ruby-1.9.1対応のパッチを取り込んで頂きました。

ss

posted by genki genki on Sat 31 Jan 2009 at 19:45 with 0 comments
Contents rssrss
光ファイバーを二次元振動させて走査するAR用ディスプレイ
因果の取り違え
Swift2's defer for CoffeeScript
mongodb-3.0からcreateIndexのdropDupsが無くなったらしい
mongodb-3.0以降のWiredTigerの設定を動的に変更する方法
一般楕円の高速生成アルゴリズムへの道標
farro mantecatoのレシピ
Droonga関連の記事のまとめ
RuntimeErrorの特定のメッセージに限定してrescueする方法
jQueryでscriptタグを実行せずにappendする
Tags
memoruby191merbお知らせgemgitpokedianewsiphonethoughtsレポートcacheclustergeneratorirbpluginrackrailsreport
Comments rssrss
瀧内元気 瀧内元気: MacOS版は以下にあります genki/ViMouse 01/16 05:40
dsjf dsjf: https://gist.github.com/6bf1bf2c3cbb5eb6e7a7 これでも出... 01/08 23:23
瀧内元気 瀧内元気: おお、チェックしてみます。thx! 12/24 05:23
overisland overisland: Reeder for iPhone もこの UI を実装していますね。 12/24 05:13
瀧内元気 瀧内元気: その情報は見たのですが、以下のサイトによると、現在はまた必要になってるっぽいんですよね。 http:... 12/01 12:20
tkawa tkawa: http://devcenter.heroku.com/articles/rails31_herok... 12/01 10:47
瀧内元気 瀧内元気: どもー。いまはgithubに置いてあります https://github.com/genki/irb... 07/10 08:31
ともち ともち: こんにちは! すばらしいプログラムをありがとうございます。しかし、merbiのドメイン、切れているみ... 07/10 02:30
Services from s21g
MagicBag
MagicBagは、Cloudflare R2やS3互換ストレージをMacのFinderから扱えるファイル同期クライアントです。
アンテナショップめぐり
東京にある全国のアンテナショップ、イベント、特産品を地図や条件から探せるサービスです。
YOMU Web小説リーダー
YOMUは、Web小説の読み上げに特化したiPhoneアプリです。
補助探
公開されている補助金・助成金情報を集約し、条件に合う制度を探しやすくするサービスです。
jotter.me
jotter.meは、考えやアイデア、情報を書き留めるためのノートサービスです。