どうもサーバが安定しないので、はてなに戻ります。
Arel is a Relational Algebra for Ruby. It 1) simplifies the generation complex of SQL queries and it 2) adapts to various RDBMS systems. It is intended to be a framework framework; that is, you can build your own ORM with it, focusing on innovative object and collection modeling as opposed to database compatibility and query generation.
「Relational Algebra」を辞書でひくと「関係代数(の演算子)」と出てきますが、arelはRDBMSのクエリを簡単に記述する為のライブラリです。使い方のイメージとしては、LINQ to SQLが一番近いと思います。ドキュメントには、
The long term goal, following both LINQ and DataMapper, is to have Arel adapt to engines beyond RDBMS, including XML, IMAP, YAML, etc.
と書かれてます。
arelを動かそうと思ったのですが、0.1.0はgemで入るもののうまく動かなかったので、0.1.3で試しました。0.1.3はactivesupport(3.0.pre)に依存してる為、Dr Nic ’s First look at rails 3.0.preを見て3.0.pre環境を作成しています。
script/consoleで動かしてみました。1 2 3 4 5 6 7 |
>> require 'arel' => [] >> tickets = Table(:tickets) => #<Arel::Table:0xb796f5c0 @engine=#<Arel::Sql::Engine:0xb7803e84 @ar=ActiveRecord::Base>, @name="tickets"> >> tickets.where(tickets[:name].matches("test%")).each do |t| >? puts t[tickets[:name]] >> end |
上記のように、SQLを気にすることなくオブジェクトの集合に対して処理を行うことができます。
ただ、値の取得に関する記述(t[tickets[:name]])や、下記に示すようにレコードの関連を使おうとすると、その記述はまだ冗長なカンジがします。1 2 3 4 |
>> tickets.join(categories).on(tickets[:category_id].eq(categories[:id])).where(categories[:name].matches("%2"))\ .each do |t| ?> puts t[tickets[:name]] >> end |
LINQ to SQLは仕事で使っていたのですがとても便利でした。arelも同じくらい使い勝手が良くなるポテンシャルがあると思います。
2部構成になっており、前半はアジャイル開発の基本的な考え方、後半はスクラム・XP・UP・Evoの各開発スタイルについて記述されています。
アジャイル開発というと、契約が分割されてないと無理、とか、顧客が付きっきりで開発に参加してもうらうのは無理、とよく言いがちです。僕も最初はよくそう思ってました。
例えば、本書の中に『「予想可能な製造」というパラダイムは、ソフトウエアには合わず、そのパラダイムに根ざしたプラクティスや価値はあまり役に立たない』という部分があります。
確かに実際は思うように行かないことが多いのも事実なのですが、ビジネスを行っていく上で計画は必要であり、それに根ざしているITが予想不可能というわけにもいかないので、うまく合わせていく必要があります。
そういった溝がある中で、顧客に対して価値を提供できることが自分たちのビジネスの根幹であり、その溝を小さくする為の手法の1つがアジャイル開発だと考えています。
だから、最近は自分たちの開発が「アジャイル開発」かどうかは気にならなくなりました。ただ、良い手法は取り入れたい、それだけです。
| 初めてのアジャイル開発 ~スクラム、XP、UP、Evoで学ぶ反復型開発の進め方~ | |
![]() | 日経BP社 2004-09-09 売り上げランキング : 23894 おすすめ平均 ![]() はじめて手にしたアジャイル本 アジャイル開発してないの? 本当のソフトウェア開発者に必要なものAmazonで詳しく見る by G-Tools |
InfoQに、Weeという継続ベースのWebアプリケーションフレームワークが紹介されていたので、試してみました。
gemでインストール後、インストールディレクトリ下のexamples/demo.rbを実行すると、自動的にWEBrickが起動します。
Counterというカウントの増減ができるページが表示され、++で1増加、--で1減算となるのですが、途中で戻るボタンを押下し、その後++/--を押下しても戻った地点から計算されます。
同じことをHTTP Sessionを使ってやると、戻るボタンを押下しても最後にsubmitした値からの加減値となり、挙動が異なります。数値をhiddenに埋め込むとできるので、この例だとメリットを感じづらいところはありますが。
Weeのアプリケーションではaction実行時にbacktrackというメソッドが呼ばれ、そこでステートを保存することができます。
1 2 3 4 |
def backtrack(state) super state.add_ivar(self, :@count, @count) end |
それがURLのpage-idと関連付けられることで、戻るボタン押下時にステートが戻るようになっているとのこと。
The solution to this problem is to take snapshots of the components state after an action is performed and restoring the state before peforming actions. Each action generates a new state, which is indicated by a so-called page-id within the URL.
次にexamples/continuation.rbを動かしてみました。こちらは、callccメソッドにMessageBoxコンポーネントを引数で渡して呼ぶと、htmlが表示されます。表示されたページにはOK/Cancelボタンがあり、どちらかを押下するかによって次の処理が決まる、というものです。
clickメソッドが1回呼び出されると、その中のcallccメソッドの呼び出し回数分(条件によって2~3回)ページが表示されている、ということになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
$LOAD_PATH.unshift "../lib" require 'rubygems' require 'wee' require 'demo/messagebox' class MainPage < Wee::Component def initialize super add_decoration(Wee::PageDecoration.new("Test")) end def click if callcc Wee::MessageBox.new('Really quit?') callcc Wee::MessageBox.new('You clicked YES') else callcc Wee::MessageBox.new('You clicked Cancel') callcc Wee::MessageBox.new('super') end end def render(r) r.anchor.callback_method(:click).with('show') end end Wee.runcc(MainPage) |
あまり継続の良さを理解できていませが、複数のリクエストに跨ってステートフルなコンポーネントを簡単に扱うことができるのがWeeの特徴の1つなのだと思います。
上記ソースのcallccはWeeのメソッドで、Kernel.callccとは異なりますが、その実装は以下のようにKernel.callccを呼び出していました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# # Similar to method #call, but using continuations. # def callcc(component) delegate = Wee::Delegate.new(component) answer = Wee::AnswerDecoration.new add_decoration(delegate) component.add_decoration(answer) answ = Kernel.callcc {|cc| answer.answer_callback = cc session.send_response(nil) } remove_decoration(delegate) component.remove_decoration(answer) return *answ.args end |
SIの仕事をしていく中で、歳を重ねる毎に様々なことを経験していきます。反面、プログラムをジックリ書くというのが年々難しくなってきていると感じてます(プログラマとしては、もう定年を過ぎているので:-))。だからこそ生産性には拘らなければなりません。
個人的にはどちらかというとツールに拘らないスタンスを取ってきました。あまりツールと生産性の相関を気にしてきませんでしたし、何より、ツールに拘らないで仕事をしている人達の仕事に憧れた、というのが単純な理由でした。
ただ、『ソフトウェア職人気質』にて「欠けているのは、既存のツールを使う為のスキルと能力」といった趣旨の記述があり、何となく気に留めていました。
そんな中で本書が紹介されているサイトを見て、偏った考え方を直す為にも一回は読んでみようと思い、購入しました。(ペンホルダーのついでですが)
結果として、本書内で紹介されているツールを導入したり、または別のツールを使って実現したりすることで、色々と整理することができました。特にデスクトップが。それだけでも読んだ甲斐がありました。
前半はツールの話が中心で、後半はコードデザインやコーディングについて記載されていますが、これはこれで別の書籍として纏められている方が良いと思いました。
| プロダクティブ・プログラマ -プログラマのための生産性向上術 | |
![]() | 島田 浩二 (監訳) オライリージャパン 2009-04-27 売り上げランキング : 34387 おすすめ平均 ![]() Javaに偏っているのが -1 気軽に読めて役に立つ、中級?ソフトウェア開発者向けの良書Amazonで詳しく見る by G-Tools |
jGrowlは、Mac OS XのGrowlをモチーフとしたメッセージを表示してくれるjQueryのプラグインです。 jQuery自体のバージョンは、1.3以上が推奨されてます。
今回はrailsのflash内のメッセージをjGrowlで表示させてみます。
1. ファイルを配置します。
1 2 3 4 5 6 |
<script type="text/javascript"> $.jGrowl.defaults.position = 'center'; <% if flash[:notice] %> $.jGrowl('<%= flash[:notice] %>', { header: 'notification', theme: 'iphone', life: 1000 }); <% end %> </script> |
‘life’で表示期間(ミリ秒)を指定します。ユーザが閉じるまで表示させたままにすることも可能です。
メッセージボードの画像とテーマ(iphone)は、jGrowlに付属しているサンプルをそのままjgrowl_custom.cssとして切り出して使っています。また、メッセージボードの表示位置について、デフォルトだとあまり選択肢がない(top-left, top-right, bottom-left, bottom-right, centerの計5種類)ので、同ファイル内で’center’の設定を上書き、表示位置を調整しました。1 2 3 4 5 |
body > div.jGrowl.center {
top: 250px;
left: 250px;
width: 0%;
} |
あとはflash[:notice]にメッセージを入れると、以下のように表示されます。

モレスキンを持ち歩くようになって2ヵ月位経ち、大分馴染んできた感があります。ただ、ペンをどう一緒に持ち歩くかだけがシックリこないので、以前MOLESKINEのエントリのコメントで教えてもらった、ペンホルダーを買いました。
今回買ったのはトラベラーズノートのペンホルダーで、MOLESKINEにうまく合うのかちょっと心配でしたが、全く問題なく付きました。良かったー。
ただ、ホルダーを付けても、ペンをどこかに置いてきてしまいそうな気はします。その心配は無くなりませんが・・・。

| トラベラーズノート ペンホルダーM【黒】 14298 | |
![]() | ミドリ 売り上げランキング : 2471 Amazonで詳しく見る by G-Tools |
近所の図書館にあったので読んでみました。
アジャイル系の開発プロセスを解説した本よりも一段上から、ソフトウェアの品質やプロセスについて記載されています。トヨタの話も出てきますが、トヨタ式が素晴らしいとかそういう話ではなく、製造と開発の違いも踏まえた上で良い部分をソフトウェア開発に用いようというスタンスで、面白かったです。
| リーンソフトウエア開発~アジャイル開発を実践する22の方法~ | |
![]() | 平鍋 健児 日経BP社 2004-07-23 売り上げランキング : 22163 おすすめ平均 ![]() 和訳が酷過ぎ ムダを排除する 自分で考えるための本ですAmazonで詳しく見る by G-Tools |
『熊とワルツを』が面白かったので、もうちょっと専門的な書籍にチャレンジしてみることに。
ソフトウェア開発プロジェクトの、ということで踏み込んだ内容を期待したのですが、別の分野でもそのまま当てはまるような一般的な内容でした。
ただ、リスク特定の手法や分析方法については『熊とワルツを』よりも詳しく紹介されており、その点で実践寄りです。
| ソフトウェア開発プロジェクトのリスク管理 | |
![]() | 富野 壽 構造計画研究所 2006-05 売り上げランキング : 389288 Amazonで詳しく見る by G-Tools |
前に読んでいた本の中で『ピープルウェア』について記述があって、確か会社にあったなぁと思って探すものの見つからず、手近にあった本書を読んでみました。
| 熊とワルツを - リスクを愉しむプロジェクト管理 | |
![]() | 日経BP社 2003-12-23 売り上げランキング : 45937 おすすめ平均 ![]() リスク管理のコア。スッキリ理解したい方に リスク管理とは リスクを理解するなら、これ1冊で十分!Amazonで詳しく見る by G-Tools |
adduserで--systemと指定すると、systemユーザを作ることができる。systemユーザっていうスキームがあるんですね。付与されるUIDの範囲以外に何か違うんだろうか。
adduser will choose the first available UID from the range specified for system users in the configuration file (FIRST_SYSTEM_UID and LAST_SYSTEM_UID). If you want to have a specific UID, you can specify it using the --uid option.
By default, system users are placed in the nogroup group. To place the new system user in an already existing group, use the --gid or --ingroup options. To place the new system user in a new group with the same ID, use the --group option.
A home directory is created by the same rules as for normal users. The new system user will have the shell /bin/false (unless overridden with the --shell option), and have logins disabled. Skeletal configuration files are not copied.
併せて、--no-create-homeを指定するとhomeディレクトリを作らない。--systemと併せて--groupを指定すると同じ名前でグループを作成してくれるので、バックグラウンドで動かすプロセスの実行ユーザを作成する場合、
adduser --system --group --no-create-home ユーザ名(グループ名) |
で良いと。
以前『ソフトウエア開発プロフェッショナル』を読んだ際に、amazonでレコメンドされていて、レビューの内容が良かったので読んでみました。
「55の真実」としつつも、その内容には否定的な表現が多く、改善方法等について明確に記載されているケースがあまり無く、個人的には忙しい時間を使ってまで読むことをお勧めしません。まだ目の前の問題に対する改善方法を考えた方が有意義でしょう。
| ソフトウエア開発 55の真実と10のウソ | |
![]() | 日経BP出版センター 2004-04-08 売り上げランキング : 44755 おすすめ平均 ![]() ソフトウェア開発の暗黙知を明文化 一人の技術者としての魂 ソフトウェア開発に携わる方は必ず読むべき名著Amazonで詳しく見る by G-Tools |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
--- lib/hikidoc.rb (リビジョン 82) +++ lib/hikidoc.rb (作業コピー) @@ -352,8 +352,12 @@ INDENTED_PRE_RE, BLOCK_PRE_OPEN_RE) def compile_paragraph(f) - lines = f.break(PARAGRAPH_END_RE)\ - .reject {|line| COMMENT_RE =~ line } + if @options[:one_line_paragraph] + lines = [f.gets] + else + lines = f.break(PARAGRAPH_END_RE)\ + .reject {|line| COMMENT_RE =~ line } + end if lines.size == 1 and /\A\0(\d+)\0\z/ =~ strip(lines[0]) @output.block_plugin plugin_block($1.to_i) else |
HikiDocのコードはとても読みやすい。
以前、仕事でマルチスレッドで動くアプリケーションを開発していたのですが、同期化の部分が思っていた以上に難しく、改めて勉強しなおせねば、と思っていました。
特に困難なのは、どういう構造で同期を取るのが良いかを決めること。同期を取る部分はもちろん言語(Java)にその機構があるので簡単なのですが、全体を考えた上で同期化の構造をスッキリした形で持たせるのはスキルが必要です。
今回はそのあたりを学習するのに最適な本として、『Java言語で学ぶデザインパターン入門【マルチスレッド編】』を選びました。
序盤は結構簡単で、今までスレッドプログラミングをしたことがあれば経験的に知っていることがパターンとして記載されています。後半は、概念は知っているけど実装したことはなかったり、概念自体もよく知らなかったり、というものが大半を占めていました。
他にもJava言語に備わっているスレッドや同期化の詳細な説明や、java.util.concurrentを使った場合の解決方法、Swingのイベントディスパッチまわりの話など、色々と勉強になります。
| 増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編 | |
![]() | ソフトバンククリエイティブ 2006-03-21 売り上げランキング : 29630 おすすめ平均 ![]() デザインパターンとは型紙(かたがみ)のことです。 分かりやすさがいい マルチスレッドを利用するなら事前に読んでおくべき本Amazonで詳しく見る by G-Tools |
「日付コントロールを変える」の最後で、プラグインの読み込みをconfig/environment.rbに記述しました。
require 'yads' |
その後調べてみたら、vendor/plugin/(プラグイン名)/init.rbで上記コードを記述すれば良いことが分かりました。各プラグインのinit.rbはrailsの初期化プロセスから自動的に呼び出される為、script/plugin install ~ でインストールすれば、フレームワークのメソッド(前回の場合はActionView::Helper::DateHelper)を再定義することができます。
でもinit.rbが自動的に呼び出されるのであれば、最初からinit.rbでメソッドの再定義を行えば良いはず。
ということで、vendor/plugin/yads/lib/yads.rbの中身をvendor/plugin/yads/init.rbに移動して実行したところ、メソッドが再定義されておらず、元々のドロップダウンリストを使った日付コントロールが表示されていました。コードは以下のとおりです。
[vendor/plugins/yads/init.rb]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# Include hook code here module ActionView module Helpers module DateHelper def date_select(object_name, method, options = {}, html_options = { }) options[:size] ||= 12 html = InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("text", options) js = <<EOS <script> $('##{object_name}_#{method}').datepicker({ dateFormat: 'yy-mm-dd'}); </script> EOS html.concat(js) end end end end |
init.rbの中でrequireして再定義するのと、init.rbの中で直接再定義することの違いが分からず、webで調べてみたところ、以下のようなページがありました。
Platte daddy: Rails plugins: keep init.rb thinRails plugins' initializer script, init.rb, is currently invoked via eval, not require—so it inherits whatever module-space Rails calls it from. If you reopen any classes in init.rb itself (like the will_paginate guys quite reasonably attempted to define Hash#slice), your changes will be made—but to the wrong module. So, to avoid strange gotchas, consider init.rb just a generic hook point to kick things off, and always require in any code that's to do actual work at plugin load time.
「If you reopen any classes in init.rb itself, your changes will be made—but to the wrong module.」と記述されているので、init.rbで再定義してもダメなのはどうも正しいようですが、その理由がわからない…。そもそもプラグインの初期化時にはフレームワークのメソッドが定義されていないのか、と考えましたが、init.rbでrequireされるファイル内で再定義してもタイミングは同じはずだし…。
requireに何か特殊な仕掛け(たとえば遅延評価とか)があるのかと思い、Rubyのrequireメソッドを再定義しているActiveSupport::Dependenciesのログを出力させてみたりしたものの、プラグインの初期化時にはログが出力されていないことから、あまり関係あるようにも思えない、という結論に至り。
プラグインのinit.rbはどのように呼び出されているか調べてみると、以下のようになっていました。
[rails-2.3.2/lib/rails/plugin.rb]1 2 3 4 5 6 7 8 9 10 |
def evaluate_init_rb(initializer) if has_init_file? silence_warnings do # Allow plugins to reference the current configuration object config = initializer.configuration eval(IO.read(init_path), binding, init_path) end end end |
evalでinit.rbを評価しているので、普通に再定義できそう…と暫く気がつかなかったのですが、evalで評価ということは呼び出し側の名前空間(今回の場合はRails::Plugin)を引き継いでしまうので、それを考慮に入れる必要がありました。つまり、init.rbで以下のように記述すると、
1 2 3 |
module ActionView module Helpers module DateHelper |
1 2 3 |
module ::ActionView module Helpers module DateHelper |
結論としては、プラグインのinit.rbでメソッドの再定義はできるものの、lib下のファイル内で再定義してinit.rbでrequireすべき。