blog移動

どうもサーバが安定しないので、はてなに戻ります。

http://d.hatena.ne.jp/hsyd/

arel

rails's arel at master - GitHub

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つがアジャイル開発だと考えています。

だから、最近は自分たちの開発が「アジャイル開発」かどうかは気にならなくなりました。ただ、良い手法は取り入れたい、それだけです。

  • 「予想可能な製造」というパラダイムは、ソフトウエアには合わず、そのパラダイムに根ざしたプラクティスや価値はあまり役に立たない
  • イテレーションが始まる直前に最善の判断にもとづいて適応型計画(状況に適応した計画)を立てること
  • イテレーションのタイムボックス化とは、イテレーションの終了日を固定し、変更させないというプラクティスである
  • 反復型ではこの不確実性に対応するため、費用や工数やスケジュールの詳細な見積りを、2,3回のイテレーションが終わるまで待って(おそらくプロジェクトの10%から20%が終わる頃に)作成する
  • 固定価格の入札で進化型の見積りを行う場合に関して、IID手法の中には(UPなど)、プロジェクトを2つの契約フェーズに分けて実行し、それぞれタイムボックスを適用したイテレーションを複数回行うよう、進めているものがある
    • 最初のフェーズは、比較的短い固定時間・定額の契約であり、2,3回のイテレーションを行って、早期のうちに部分的なソフトウエア開発および進化型の要求分析を行うことが目標である
    • フェーズ1の成果物を確認して行う為、フェーズ2の見積りに役立つ質の高いデータが集まり、しかもプロジェクトのソフトウエア開発も進む
  • アジャイル宣言
    • プロセスやツールよりも、個人相互作用
    • 包括的なドキュメントよりも、動作するソフトウエア
    • 契約交渉よりも、顧客との協調
    • 計画に従うことよりも、変化に対応すること
  • アジャイル原則
    • 最も重要なことは、価値のあるソフトウェアを早い段階から継続的に納品し、顧客を満足させること
    • たとえ開発が進んだ後であっても要求の変更を歓迎する。アジャイルなプロセスとは、顧客の競争優位のために変化を生かすもの
    • 動くソフトウエアを頻繁に納品する。その間隔は2、3週間から2、3ヵ月月の単位で、短いほど良い
    • ビジネスサイドの人間と開発者が、プロジェクト全体を通じて毎日一緒に仕事をする
    • やる気のある個人を中心にプロジェクトを構築する。環境を整え、必要なものを提供し、仕事をやり遂げてくれる信じること
    • 開発チームに対して、あるいは開発チーム内で情報を伝えるために最も効率的かつ有効な方法は、直接の対話である
    • 動くソフトウエアこそが進捗を測る一番の尺度である
    • アジャイルなプロセスは、継続的な開発を促進する。スポンサー、開発者そしてユーザが一定のペースを無期限に保たなければならない
    • 技術卓越性と優れた設計に常に注意を払うことが、アジャイルさを向上させる
    • 簡潔性(できるかぎり作業をしないですませる術)こそ本質である。
    • 最も優れたアーキテクチャ、要求、設計は、は自己組織化されたチームから創発されるものである
    • チームは定期的に、より効果的な方法を検討し、自分たちのやり方を調整し適合させる
  • アジャイルプロジェクトマネジメント
    1. クライアントにとって有用なものを出荷する。何が重要視されるかを確認する
    2. 利害関係者が熱心に参加するように育てる
    3. リーダーシップ-コラボレーション方式を採用する
    4. 有能且つ協調的なチームを作り上げる
    5. チームが意思決定できるようにする
    6. タイムボックスを短く区切ったイテレーションを行って、早期にユーザ機能を出荷する
    7. 適応性を高める
    8. 技術的卓越性を擁護する
    9. プロセスに準拠するための作業ではなく、出荷するための作業を重視する
  • オーガスティンとウッドコックの6つのプラクティス
    • 指針となるビジョン: プロジェクトの指針となるビジョンを打ち立て、言葉と行動の両方から継続的に補強する
    • チームワークとコラボレーション: 関係とコミュニティを通してコラボレーションとチームワークを活性化する
    • シンプルなルール: スクラムやXPなどのようにチームの指針となる一連のプラクティスを設定し、サポートする
    • 情報の公開: プロジェクトマネジメントなどの情報を公開してアクセスできるようにする
    • 軽いタッチ: 自律的チームの創発的な振る舞いを促進するために最低限の管理だけを行う
    • アジャイルな自戒: ビジョンを補強し、ルールをそのまま、あるいはカスタマイズして適用し、人の言うことに耳を傾ける
  • 健全な開発チームは複雑適応系である。一羽一羽の鳥は限られた中の単純なルールに従って振舞っているが、マクロの視点では、群れは秩序と集団の創発的振る舞いを示す
  • プロジェクトの要求変更の割合は、中規模で25%、大規模では35%を超える
  • スプリントバックロググラフ(タスクの推定残作業時間をグラフに纏めたもの)を用いる
  • 広域デルファイ法を使った見積りを検討する
  • ムーア式ビジョン記述
    • (ニーズや機会の記述)であるところの
    • (対象顧客)向けに作られた
    • この(製品/システム名)は(製品/システムカテゴリ)である
    • これによって(主な利点、つまり購入せざるをえない理由の記述)が得られる
    • 主な競合製品/システムとは異なり
    • この製品/システムは(主な差異の記述)という点で優れている
初めてのアジャイル開発 ~スクラム、XP、UP、Evoで学ぶ反復型開発の進め方~
初めてのアジャイル開発 ~スクラム、XP、UP、Evoで学ぶ反復型開発の進め方~
日経BP社 2004-09-09
売り上げランキング : 23894

おすすめ平均 star
starはじめて手にしたアジャイル本
starアジャイル開発してないの?
star本当のソフトウェア開発者に必要なもの

Amazonで詳しく見る
by G-Tools

Weeで継続

InfoQに、Weeという継続ベースのWebアプリケーションフレームワークが紹介されていたので、試してみました。

gemでインストール後、インストールディレクトリ下のexamples/demo.rbを実行すると、自動的にWEBrickが起動します。

Counterというカウントの増減ができるページが表示され、++で1増加、--で1減算となるのですが、途中で戻るボタンを押下し、その後++/--を押下しても戻った地点から計算されます。

Counter

同じことを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の仕事をしていく中で、歳を重ねる毎に様々なことを経験していきます。反面、プログラムをジックリ書くというのが年々難しくなってきていると感じてます(プログラマとしては、もう定年を過ぎているので:-))。だからこそ生産性には拘らなければなりません。

個人的にはどちらかというとツールに拘らないスタンスを取ってきました。あまりツールと生産性の相関を気にしてきませんでしたし、何より、ツールに拘らないで仕事をしている人達の仕事に憧れた、というのが単純な理由でした。

ただ、『ソフトウェア職人気質』にて「欠けているのは、既存のツールを使う為のスキルと能力」といった趣旨の記述があり、何となく気に留めていました。

そんな中で本書が紹介されているサイトを見て、偏った考え方を直す為にも一回は読んでみようと思い、購入しました。(ペンホルダーのついでですが)

結果として、本書内で紹介されているツールを導入したり、または別のツールを使って実現したりすることで、色々と整理することができました。特にデスクトップが。それだけでも読んだ甲斐がありました。

前半はツールの話が中心で、後半はコードデザインやコーディングについて記載されていますが、これはこれで別の書籍として纏められている方が良いと思いました。

  • 気をちらす要因を排除する
  • 「沈黙の時間」を作る
  • ナビゲーションより検索
  • ルートビューを使う
  • 仮想デスクトップを使って、作業毎にデスクトップを切り替える
  • 自動化する為にスクリプトを書く
    • Excelで複数のワークシートを開く
  • Webアプリケーションの操作記録にSeleniumを利用する
  • バッチファイルではなくWindows PowerShellを使う
  • コードを基に図を生成する
  • コード解析を使う
    • PMD
    • Panopticode
  • Calendarの代わりにJodaライブラリを使う
  • DSLを導入する(Neptune)
プロダクティブ・プログラマ -プログラマのための生産性向上術
プロダクティブ・プログラマ -プログラマのための生産性向上術島田 浩二 (監訳)

オライリージャパン 2009-04-27
売り上げランキング : 34387

おすすめ平均 star
starJavaに偏っているのが -1
star気軽に読めて役に立つ、中級?ソフトウェア開発者向けの良書

Amazonで詳しく見る
by G-Tools

jGrowl

jGrowlは、Mac OS XのGrowlをモチーフとしたメッセージを表示してくれるjQueryのプラグインです。 jQuery自体のバージョンは、1.3以上が推奨されてます。

今回はrailsのflash内のメッセージをjGrowlで表示させてみます。

1. ファイルを配置します。

  • $RAILS_ROOT/public/javascripts/jquery.jgrowl.js
  • $RAILS_ROOT/public/stylesheets/jquery.jgrowl.css
  • $RAILS_ROOT/public/stylesheets/jgrowl_custom.css(サンプルから一部切り出したテーマの設定)
  • $RAILS_ROOT/public/images/iphone.png(サンプルにあったiphoneライクなメッセージボードの画像)

2. railsのflashの内容が表示されるよう、.html.erb内にJavaScriptを記述します。
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]にメッセージを入れると、以下のように表示されます。

jGrowl
















トラベラーズノート ペンホルダー

モレスキンを持ち歩くようになって2ヵ月位経ち、大分馴染んできた感があります。ただ、ペンをどう一緒に持ち歩くかだけがシックリこないので、以前MOLESKINEのエントリのコメントで教えてもらった、ペンホルダーを買いました。

今回買ったのはトラベラーズノートのペンホルダーで、MOLESKINEにうまく合うのかちょっと心配でしたが、全く問題なく付きました。良かったー。

ただ、ホルダーを付けても、ペンをどこかに置いてきてしまいそうな気はします。その心配は無くなりませんが・・・。

ペンホルダ
ペンホルダ posted by (C)masayuki
トラベラーズノート ペンホルダーM【黒】 14298
トラベラーズノート ペンホルダーM【黒】 14298
ミドリ
売り上げランキング : 2471


Amazonで詳しく見る
by G-Tools

リーンソフトウエア開発~アジャイル開発を実践する22の方法~

近所の図書館にあったので読んでみました。

アジャイル系の開発プロセスを解説した本よりも一段上から、ソフトウェアの品質やプロセスについて記載されています。トヨタの話も出てきますが、トヨタ式が素晴らしいとかそういう話ではなく、製造と開発の違いも踏まえた上で良い部分をソフトウェア開発に用いようというスタンスで、面白かったです。

  • 「原則」が、ある分野についての指針となる考えや洞察であるのに対し、「プラクティス」は、原則を実行するために、何をするか
  • ソフトウェア開発の7つの無駄
    • 未完成の作業のムダ
    • 余分なプロセスのムダ
    • 余分な機能のムダ
    • タスク切り替えのムダ
    • 待ちのムダ
    • 移動のムダ
    • 欠陥のムダ
  • プロジェクトのトラッキングが複雑なら、おそらくそのシステムには、ほかの種類のムダが大量にある
  • 開発(レシピを設計する)
    • 実践利用に適していることが品質の基準
    • バリエーションがある結果は善
    • 反復は価値を無味出す
  • 高レベルの設計と詳細な解法の間を行き来する
  • フィードバックを増やすことが、問題のあるソフトウェアプロジェクトや環境に対処する唯一の効果的な方法
    • 欠陥をためこまず、コードを書いてすぐにテストすること
    • ドキュメントや詳細な計画を増やすのではなく、コードを書くことによって考えが正しいことを確認する
    • 多くの要求をユーザから集めるのではなく、どのようなことができるかをユーザに見せ、ユーザから入力を得ること
    • どのツールを使うかを入念に調べるのではなく、組織内での候補を3つ選び、それらを試してみる
    • システム全体を一度に置き換える方法を見つけようとするのではなく、レガシーシステムにウェブインターフェースをつける、という新しいアイデアを試してみる
  • あきらかに多くのリソースを費やして、多数のコンセプトを検討する。それにより、開発プロセス全般に渡って多数のオプションを選択できる状態に保ち、サブシステムのプロトタイプを多数作り出す
  • ウェブサイトの構造について合意できない場合、2,3バージョンを用意し、それぞれ異なる画面遷移やページレイアウトを行うようにして、最終的に最高の機能を寄せ集めることで、優れたユーザビリティの点数が取れる
  • 深さ優先のシーケンシャル開発と、広さ優先のコンカレント開発がある
  • ソフトウェア開発でのコミットメントを遅らせるための戦略
    • モジュールを使う
    • インターフェースを使う
    • パラメータ化する
    • 抽象化を使う
    • シーケンシャルプログラミングを避ける
    • フレームワークは成功した実装を集めた中から抽出されるべきで、推測で作らない
  • ソフトウェア開発の7つのシンプルルール
    1. ムダをなくす
    2. 学習効果を高める
    3. 決定をできるだけ遅らせる
    4. できるだけ速く提供する
    5. チームに権限を与える
    6. 統一性を作り込む
    7. 全体を見る
  • チームでプロセスをチェックする
    1. 何があなたをスピードダウンささているのか、また、何がいい仕事をするじゃまをしているのか
    2. もっと速く、よく、安くするためには、何が役立つか?いいプラクティスと悪いプラクティスを作ること
  • リーンソフトウエア開発~アジャイル開発を実践する22の方法~
    リーンソフトウエア開発~アジャイル開発を実践する22の方法~平鍋 健児

    日経BP社 2004-07-23
    売り上げランキング : 22163

    おすすめ平均 star
    star和訳が酷過ぎ
    starムダを排除する
    star自分で考えるための本です

    Amazonで詳しく見る
    by G-Tools

ソフトウェア開発プロジェクトのリスク管理

『熊とワルツを』が面白かったので、もうちょっと専門的な書籍にチャレンジしてみることに。

ソフトウェア開発プロジェクトの、ということで踏み込んだ内容を期待したのですが、別の分野でもそのまま当てはまるような一般的な内容でした。

ただ、リスク特定の手法や分析方法については『熊とワルツを』よりも詳しく紹介されており、その点で実践寄りです。

  • プロジェクトの主要な原因は、管理的課題65%、技術的課題35%
  • 組織でリスクを管理する仕組みを作る
  • リスク軽減シナリオ
    • プロジェクトの範囲を定める
    • 初期のシナリオを作成する
    • シナリオを分析する
    • 問題と課題を位置づける
    • 主要リスク領域
    • 軽減戦略を作成し、公表する
  • リスクパラダイム
    • 特定
    • 分析
    • 計画
    • 追跡
    • 制御
  • 計画を策定する
    • リスク発生時の不測事態態対応計画を作成してリスクの影響を軽減する
    • 製品の設計あるいは開発プロセスを変更することによりリスクを回避する
    • リスクを受容する。問題が発生した場合は受け入れ、特別な行動をとらない
    • 多くの情報を取得し、リスクの特性をさらに研究する
  • リスク特定の手法
    • プレーンストーミング
    • SWOT分析
    • マップ
    • チェックリスト
    • ピアインタビュー
  • リスク対応にかかわる3つの重要な要因
    • 要員数、期間、費用、影響部門数などのプロジェクト規模
    • 技術的熟練レベル、用いられる新技法、設計の技術的困難性や類似プロジェクトの経験等
    • 明確な要求、確定的で確定な成果、プロジェクト期間中における仕様変更がないなどのプロジェクト構造
  • リスクレビューのタイミングは早い方が良いが、リスクについて十分に考察されていない時点で行ってもいけない
  • デシジョンツリー分析の6つの基本ステップ
    1. なされるべき決断とその決断により起こりえ結果を示す
    2. 各不確定事象に発生確率を指定する
    3. 起こりえる結果に対して価値を割り振る
    4. それぞれの代替案について期待値を計算する
    5. なされるべき決断に関連するソフト要因を解く手する
    6. 最善の代替案を決定する
  • 定量市場調査
    • リスクについて、どのようなデータを収集する必要があるか
    • データをどのように取得すべきか
    • どのように実行するか
    • 結果をどのように解釈するか
    • 結果をどのように利用するか
ソフトウェア開発プロジェクトのリスク管理
ソフトウェア開発プロジェクトのリスク管理富野 壽

構造計画研究所 2006-05
売り上げランキング : 389288


Amazonで詳しく見る
by G-Tools

熊とワルツを

前に読んでいた本の中で『ピープルウェア』について記述があって、確か会社にあったなぁと思って探すものの見つからず、手近にあった本書を読んでみました。

  • 目の前にある証拠をもとに、そのスケジュールが可能だと信じる権利があったのか
  • リスクのないプロジェクトには手をつけるな
  • リスク管理は、問題が発生する前の、抽象的な概念の段階で対策を考えるプロセス
  • リスク管理の反対を「危機管理」といい、問題が発生した後に何をするべきかを考えることを意味する
  • リスク管理の各構成要素
    • リスク発見: まずリスクに関するブレストを行い、次にリスクを選別する。さらにプロセスを継続する仕組みを導入する
    • エクスポージャー分析: それぞれのリスクが発生する確率と、それによる影響を数量化する
    • 危機対応管理: リスクが実現した場合に、何をするべきかを計画する
    • 軽減: 計画した危機対応措置が必要な時に実行でき、効力を持つように、移行前にとるべき対策をとる
    • 継続的な移行監視: 管理するリストを追跡し、実現しないかどうかを監視する
  • 不確定性を口に出すことができない企業文化の中では、リスク管理はできない
  • リスクについてできること
    • 避ける
    • 抑制する
    • 軽減する
    • かわす
  • リスクを評価するツールを使う(RISKOLOGY)
  • ソフトウェア・プロジェクトのコアリスク
    • 内在的なスケジュールの欠陥
    • 要求の増大(変更)
    • 人員の離脱
    • 仕様の崩壊
    • 生産性の低迷
  • リスクを特定するためのプロセス
    • 破滅的結果についてのブレスト
    • シナリオの構築
    • 根本原因の分析
  • インクリメンタル開発
    • 開発計画及び詳細設計と、インプリメンテーションが時間的に重複しないようにする
    • 作業分割を最低レベルまで行い、進捗メトリックを計測する
  • ショーストッパー(権限を越えたリスク)を見極める
  • 熊とワルツを - リスクを愉しむプロジェクト管理
    熊とワルツを - リスクを愉しむプロジェクト管理
    日経BP社 2003-12-23
    売り上げランキング : 45937

    おすすめ平均 star
    starリスク管理のコア。スッキリ理解したい方に
    starリスク管理とは
    starリスクを理解するなら、これ1冊で十分!

    Amazonで詳しく見る
    by G-Tools

adduser

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 ユーザ名(グループ名)

で良いと。

ソフトウエア開発 55の真実と10のウソ

以前『ソフトウエア開発プロフェッショナル』を読んだ際に、amazonでレコメンドされていて、レビューの内容が良かったので読んでみました。

「55の真実」としつつも、その内容には否定的な表現が多く、改善方法等について明確に記載されているケースがあまり無く、個人的には忙しい時間を使ってまで読むことをお勧めしません。まだ目の前の問題に対する改善方法を考えた方が有意義でしょう。

  • ソフトウエアの世界は、人的資質の研究が最も重要
  • 人がじっくり考えた結果の見積りは、かなり精度が高い
  • 実現できそうもない工程を何とか間に合わせるあまり、プログラムの完全性や品質を犠牲にする
  • プログラマを制御することに重点を置くマネジメントでは、最高のプロジェクトになりえないし、生産性も低くなる
  • 「成功したプロジェクトとは何か」を定義できないならば、整理が必要な大問題が残っていることになる
  • 大規模な再利用は当分うまくいかない。本来、この問題は、ソフトウエアの多様性に根ざした解決困難な問題なのである
  • 非常に狭いドメインでは、大規模な再利用が成功する確率は大きくなる。色々なプロジェクトをまたがったり、異なるドメインを横断するような再利用は、失敗する可能性も高い
  • 対象となる問題の複雑度が25%増加するたび、ソフトウエアによる解法の複雑度は100%上昇する
  • インスペクションをしっかり実施すれば、実機でプログラムを走らせる前に、最高90%の不良を摘出できる
  • 優れたプログラムが備えるべき7つの属性
    1. 移植性
    2. 信頼性
    3. 効率
    4. 人間工学(UI)
    5. 検証性(プログラムを容易にテストできる特性)
    6. 理解容易性
    7. 変更容易性
  • 規模が大きく、基幹ソフトウエアの開発において、プロジェクト内の規則をきちんと定めたケースでは、アジャイル開発よりも効果があるケースもある
ソフトウエア開発 55の真実と10のウソ
ソフトウエア開発 55の真実と10のウソ
日経BP出版センター 2004-04-08
売り上げランキング : 44755

おすすめ平均 star
starソフトウェア開発の暗黙知を明文化
star一人の技術者としての魂
starソフトウェア開発に携わる方は必ず読むべき名著

Amazonで詳しく見る
by G-Tools

HikiDocで1行でも段落とする

HikiDocでは、改行だけの行か、他の要素(ヘッダーやリスト等)が見つかるところまでを段落としています。例えば、”ふー\nばー\nほげ\n”だと1段落になります。 今回、これを3段落にしたい、つまり改行があったらそこまでを段落としたい、ということになり、HikiDocのソースを読んでみた結果、以下の変更を加えることでできました。
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
オプションに、{:one_line_paragraph => true}を指定すると、1行を段落としてくれます。

HikiDocのコードはとても読みやすい。

Java言語で学ぶデザインパターン入門【マルチスレッド編】

以前、仕事でマルチスレッドで動くアプリケーションを開発していたのですが、同期化の部分が思っていた以上に難しく、改めて勉強しなおせねば、と思っていました。

特に困難なのは、どういう構造で同期を取るのが良いかを決めること。同期を取る部分はもちろん言語(Java)にその機構があるので簡単なのですが、全体を考えた上で同期化の構造をスッキリした形で持たせるのはスキルが必要です。

今回はそのあたりを学習するのに最適な本として、『Java言語で学ぶデザインパターン入門【マルチスレッド編】』を選びました。

序盤は結構簡単で、今までスレッドプログラミングをしたことがあれば経験的に知っていることがパターンとして記載されています。後半は、概念は知っているけど実装したことはなかったり、概念自体もよく知らなかったり、というものが大半を占めていました。

他にもJava言語に備わっているスレッドや同期化の詳細な説明や、java.util.concurrentを使った場合の解決方法、Swingのイベントディスパッチまわりの話など、色々と勉強になります。

  • Single Threaded Execution
    • クリティカルセクションを見極める
  • Immutable
    • finalを使った宣言
    • インスタンスフィールドがimmutableかどうか
  • Guarded Suspension
    • Spin Lock
    • ガード条件が満たされていなければスレッドを待たせる
    • ガード条件のテストにwhileを、待たせる為にwaitを使う
  • Balking
    • ガード条件が満たされていなければ実行を中断
    • ガード条件のテストにifを、balkにはreturnかthrowを使う
  • Producer-Consumer
    • Channel役を配置する
    • データの安全性をChannelが管理する
    • 安全にデータを受け渡しする部分では、Guarded Suspentionを使う
    • executionのキャンセル可能
  • Read-Write Lock
    • Readのみであれば排他は不要
    • Readしている時はWriteできない
    • Writeしている時はRead/Writeができない
    • Writeしている時はRead/Writeができない
    • Read/Writeを管理するReadWriteLock役を置く
  • Thread-Per-Message
    • 処理の順序を気にしないときに使う
    • 戻り値が必要な場合はFutureを使う
    • スレッドは要求の度に起動する
  • Worker Thread
    • 処理を実行するスレッドを予め起動しておく
    • ワーカスレッドに渡すリクエストは継承を意識する
    • リクエストをワーカスレッドに安全に渡す(Producer-Consumer)
    • invocationとexecutionの分離
  • Future
    • 処理の実行結果を後から取得する
    • 処理が非同期(Thread-Per-MessageやWorker Threadの場合に用いる
    • 実行結果取得時にはGuarded Suspensionを使用する
  • Two-Phase Termination
    • どこで処理が中断されても安全に終了する
    • Thread#stopを使わない
    • Thread#isInterruptedを使わない
    • 終了要求が来たことをラッチを使って判断する
  • Thread-Specific Storage
    • Thread Localの他に、スレッドの属性として保存する方法もある
    • スループットに主眼を置かれているというよりも、
      • プログラムの構造を変えずにすむ
      • 排他制御が表に出てこないので、誤りをおかす危険がすくない
      という再利用性に主眼を置いている
    • コンテキストは処理に本当に使われている情報が何かが曖昧になる危険性がある
  • Active Object
    • 自分固有のスレッドを持つ
    • 非同期メッセージの実現
    • Scheduler役を置く
    増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編
    増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編
    ソフトバンククリエイティブ 2006-03-21
    売り上げランキング : 29630

    おすすめ平均 star
    starデザインパターンとは型紙(かたがみ)のことです。
    star分かりやすさがいい
    starマルチスレッドを利用するなら事前に読んでおくべき本

    Amazonで詳しく見る
    by G-Tools

pluginのinit.rbでメソッドを再定義できない理由

日付コントロールを変える」の最後で、プラグインの読み込みを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 thin

Rails 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
「Rails::Plugin::ActionView::Helpers::DateHelper」を定義していることになるという…。なので、「::ActionView」と書けば再定義することができます。
1
2
3
module ::ActionView
  module Helpers
    module DateHelper

結論としては、プラグインのinit.rbでメソッドの再定義はできるものの、lib下のファイル内で再定義してinit.rbでrequireすべき。