tridentをGem化してリリースしました - Hello, world! - s21g

tridentは、 tail -f log/development.logと autotest、script/console を一枚の端末上で同時に実行するRailsプラグインでした(trident: tail -f, autotest and script/console at once参照)

便利すぐる。使わない人には宗教上の理由が必要ですね?

% trident
Rendered cemeteries/_cemetery (0.00263)
Rendered shared/_page_header (0.00083)
Rendered shared/_header_other (0.00068)
Prefecture Load (0.000395) SELECT * FROM `prefectures` WHERE (`prefectures`.`id` IN (10,11,12,13,14,19,22,23,26,27,28,29))
CACHE (0.000000) SELECT * FROM `costs`
Character Load (0.000364) SELECT * FROM `characters`
Character Columns (0.001453) SHOW FIELDS FROM `characters`
Rendered cemeteries/_finder (0.01049)
Rendered shared/_page_footer (0.00073)
Completed in 0.19417 (5 reqs/sec) | Rendering: 0.12335 (63%) | DB: 0.02105 (10%) | 200 OK [http://tsuisumi/cemeteries]
Loading development environment (Rails 2.0.2)
loading autotest/rails_rspec
./vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb:17: warning: method redefined; discarding old group_by
./vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb:8: warning: discarding old start_with?
./vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb:9: warning: discarding old end_with?
SQL (0.000168) SET NAMES 'utf8'
SQL (0.000089) SET SQL_AUTO_IS_NULL=0
SQL (0.097719) SELECT version FROM schema_info
>> Cemetery.find(1).name
Cemetery Columns (0.028357) SHOW FIELDS FROM `cemeteries`
Cemetery Load (0.000333) SELECT * FROM `cemeteries` WHERE (`cemeteries`.`id` = 1)
=> "駒形霊園"

WordPressにはContact Form 7というお問い合わせフォームが簡単に出来るプラグインがあるそうです。

しかし、さくらインターネットのスタンダードプランの様な共有SSLを使っている場合はformのactionが別のURLを指す必要があるので動きません。PHPでベタにお問い合わせフォームの作成を依頼されたんですが、面倒なのでContact Form 7を修正してWordPress本体とは別のURLで動くようにしました。

% diff wp-content/plugins/contact-form-7/settings.php{,.org}
115c115
<       return (string) 'https://secure1111.sakura.ne.jp/example.com'.$wpcf7_request_uri;
---
>       return (string) $wpcf7_request_uri;

多分、WebサーバーがURLを書き換えているので環境変数から現在のREQUEST_URIが取れない。仕方なくベタにURLを書きました。javascriptでfromのactionを書き換えれば汎用的になりそうですがそれはキモイのでこれでいいや。

参照:Contact Form 7: WordPress のお問い合わせフォームプラグイン。シンプル、でも柔軟。

第2章 基本的なデータ型

2.1 整数

# 3 ;;
- : int = 3
# 3 + 4 * 2 ;;
- : int = 11
# (3 + 4) * 2 ;;
- : int = 14
# 2 - 3 ;;
- : int = -1
# 7 / 2 ;;
- : int = 3
# 7 mod 2 ;;
- : int = 1
問題2.1 次の整数値をOCamlインタプリタを使って計算せよ。

(1) 7 – 3 × 4

# 7 - 3 * 4 ;;
- : int = -5

(2) 7 ÷ 2 × 2

# 7 / 2 * 2 ;;
- : int = 6

(3) 7 × 2 ÷ 2

# 7 * 2 / 2 ;;
- : int = 7

2.2 実数

# 2.718 ;;
- : float = 2.718
# (3.0 +. 5.0) *. 8.0 /. 3.0 ;;
- : float = 21.3333333333333321
# (3. +. 5.) *. 8. /. 3. ;;
- : float = 21.3333333333333321
# 1.41421356 ** 2.0 ;;
- : float = 1.99999999328787381
# 1.41421356 ** 2 ;;
Error: This expression has type int but an expression was expected of type
 float
# 1.41421356 ** 2.0 ;;
- : float = 1.99999999328787381

んんん、実数キモイ・・・。

問題2.2 次の実数値をOCamlインタプリタを使って計算せよ。

(1) 2・3.14・10

# 2. *. 3.14 *. 10. ;;
- : float = 62.8000000000000043

(2) 1.732

# 1.73 ** 2. ;;
- : float = 2.9929

(3) 7/2

(* 間違い *)
# 7 / 2 ;;
- : int = 3
(* 正解 *)
# 7. /. 2. ;;
- : float = 3.5
# infinity ;;
- : float = infinity
# infinity +. 3.0 ;;
- : float = infinity
# 2.0 /. infinity ;;
- : float = 0.
# neg_infinity ;;
- : float = neg_infinity
# 3.0 -. infinity ;;
- : float = neg_infinity

2.3 文字列

# "Yokohama" ;;
- : string = "Yokohama" 
# "横浜" ;;
- : string = "横�\156" 
# "横浜" ^ "駅" ;;
- : string = "横�\156�\133" 
# "新" ^ "横浜" ^ "駅" ;;
- : string = "�\150�横�\156�\133" 
# "" ;;
- : string = ""
問題2.3 次のそれぞれの文字列をOCamlインタプリタに入力せよ。次に、それらの文字列を結合してみよ。

(1) 「東京」、「特許」、「許可局」、「局長」

# "東京" ^ "特許" ^ "許可局" ^ "局長" ;;
- : string = "�\157�京�\137�許許�\143��\128�\128�\149�"

(2) 「関数」、「型」、「言語」

# "関数" ^ "型" ^ "言語" ;;
- : string = "�\150��\149��\158\139�\128�\158"

2.4 真偽値

# true ;;
- : bool = true
# false ;;
- : bool = false
# true && true ;;
- : bool = true
# true && false ;;
- : bool = false
# true || false ;;
- : bool = true
# false || false ;;
- : bool = false
# not true ;;
- : bool = false
# not false ;;
- : bool = true
# not (false || not false && not false) ;;
- : bool = false
# not (false || ((not false) && (not false))) ;;
- : bool = false
# 2 < 3 ;;
- : bool = true
# 2 < 3 && 2.0 > 3.0 ;;
- : bool = false
# 2 < 3 || 2.0 = 3.0 ;;
- : bool = true
# not (3 < 2) ;;
- : bool = true
# true > false ;;
- : bool = true
# false > true ;;
- : bool = false
# true > true ;;
- : bool = false
# 2 < 3.0 ;;
Error: This expression has type float but an expression was expected of type
 int
問題2.4 次の文章の真偽をOCamlインタプリタを使って確認せよ。

(1) 2は3より大きい。

# 2 > 3 ;;
- : bool = false

(2) 3.1415の2乗より10は小さくない。

# not (3.1415 ** 2.0 > 10.0) ;;
- : bool = true

(3) 8を3で割った余りは2である。

# 8 mod 3 = 2 ;;
- : bool = true

(4) 3 4 5 と4 × 3は等しい。

# (3 + 4 + 5) = (4 * 3) ;;
- : bool = true

lispみたいvimで選択範囲を評価するみたいなプラグインがほしい・・・。

こちらのエントリーで書いてたのをちょっと何とかならないか探って見ました。

(あくまで個人的なHackなので本家には問い合わせたりしないようお願い致します。)

JSONをただ引っ張って来てPlayerに渡してるだけだろうと思って、Javascriptの中でsortできないかと少し探りました。

jsはどうも勘が働かず、Firebugsで追ってもいまいち分からず。(そもそも動画サイト毎のプラグインアーキテクチャー的なものとか、なんでニコ動再生できんの?とかいうレベルで分からない。)

やはりサーバーサイドか・・・。

インストール中にチラチラ見えていたMoose?とか、Rose::DBとかHTTP::Engineとか大昔に止まっている俺のPerl脳で理解できるんだろうか。あぁ・・・巨大なモダンPerlが攻めて来る

と思ったら意外に読み易い。(Remedieのソースが綺麗なのかも)

実装方法は違えど、設計はどの言語も似たようなもんで、Rubyで言えばアレか〜って感じで理解し易かった。

Rose::DB::Object::Managerなんて糞便利なもんがあるんですね。(Class::DBIとかで時が止まっている。)

本題。

remedie 0.6.14へのdiffです。

diff --git a/lib/Remedie/DB/Channel.pm b/lib/Remedie/DB/Channel.pm
index da0597f..f2bde7d 100644
--- a/lib/Remedie/DB/Channel.pm
+++ b/lib/Remedie/DB/Channel.pm
@@ -19,7 +19,7 @@ sub items {

     return Remedie::DB::Item::Manager->get_items(
         query => \@query,
-        sort_by => 'id DESC',
+        sort_by => 'id',
         $opts{limit} ? (limit => $opts{limit}) : (),
     );
 }

Remedie: マイリスト FF5 モンク縛り‐ニコニコ動画(ββ)

キタコレ。

これでニコ動の続きモノ動画を大消化大会だ!

追記:

こっちの方がスマート。

Twitter / toshikaz: remedieにゲーム実況などニコニコマイリストを登 …

toshikaz55 remedieにゲーム実況などニコニコマイリストを登録する際に逆順になる場合は、RSSのURLに、/mylist/XXXXXX?sort=d&rss=2.0 とsortを付加してやると順番に登録されて楽に順次再生できる

関連

参照

Redmineのタスクの更新メール、自分に関係あるものだけ届くようにしてるんですが、複数のプロジェクトが平行して動いているのでいかんせん数が多い。(ミーティングが多い日などは1日でいきなり100通超える)

Gmailでj,kを使ってどんどん見て行くんですが、最近高速に処理するコツが分かって来た。

チケットメールを素早く処理するコツ

基本、(HTMLメールにした場合)このhr線から上だけを見て行けばサクサク処理できる。

[いこーよ </del> 新機能 #1662] いこーよをRails 2.3.3へいこーよ。 <del> komagata@gmail.com </del> Gmail

  • ハマってるところで知ってることがあったら「たしかxxxってブログに乗ってましたよー」とか書く。
  • チケットの内容がよくわからない場合は「イミフ」とだけ書くと、チケット作成者が内容を見直すという合意をしておく。

チケット作成で繰り返し起きるコミュニケーションミスを減らすコツ

新規チケットを作る時にテキストエリアにデフォルトのテンプレを設定しておくと書かなきゃ行けないことがわかりやすい。(特に終了条件が曖昧だと作業者は非常にやり辛い。明確な成果物やエビデンスを残すことをゴールにすると上手く行く。)

「xxxを考える/決定するという」タスクが乱立するしていたら、「xxxの内容をまとめてxxxさんにメールする」「Googleサイトに内容をまとめる」などに変更すると終了条件が明確化する。

いこーよ </del> Redmine(タスク管理)

デフォルトテンプレを入れるredmine 0.8系trunkへのdiff:

Index: app/controllers/issues_controller.rb
===================================================================
--- app/controllers/issues_controller.rb        (リビジョン 2819)
+++ app/controllers/issues_controller.rb        (作業コピー)
@@ -115,6 +115,7 @@
     @issue = Issue.new 
     @issue.copy_from(params[:copy_from]) if params[:copy_from]
     @issue.project = @project
+    @issue.description ||= l(:default_issue_description)
     # Tracker must be set before custom field values
     @issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
     if @issue.tracker.nil?
Index: lang/ja.yml
===================================================================
--- lang/ja.yml (リビジョン 2819)
+++ lang/ja.yml (作業コピー)
@@ -635,9 +637,10 @@
 setting_mail_handler_api_key: APIキー
 text_email_delivery_not_configured: "メールを送信するために必要な設定が行われていないため、メール通知は利用できません。\nconfig/email.ymlでSMTPサーバの設定を行い、アプリケーションを再起動してください。" 
 field_parent_title: 親ページ
-label_issue_watchers: Watchers
+label_issue_watchers: ウォッチャー
+default_issue_description: "h3. 目的\n\n(何故このタスクをする必要があるのか)\n\nh3. 終了条件\n\n# (終了条件1)\n# (終了条件2)\n# (終了条件3)" 
 setting_commit_logs_encoding: コミットメッセージのエンコーディング
-button_quote: Quote
+button_quote: 引用
 setting_sequential_project_identifiers: プロジェクト識別子を連番で生成する
 notice_unable_delete_version: バージョンを削除できません
 label_renamed: renamed

Redmine上だけで問題を追跡するコツ

  • チケット解決時には関連するリビジョン番号を入れる「r654 で修正」とリポジトリブラウザにリンクが張られる。
  • svnとかのフックの設定をしておくて、コミットログに「fixes #1234」とか書くだけで“解決”+“進捗100%”にしてくれると同時にリポジトリブラウザからチケットへのリンクが張られる。
  • コード上の気になるところはコードレビュープラグインで疑問を書いておく。

開発人数をスケールさせるにはRailsの設計思想みたいに、開発環境も中央集権的ではなくて、「何も共有しない」というようにすると上手くいくなあと感じます。 (リモートからのみの作業者と共同で開発する場合)

会社(アクトインディ)ではRedmineのチケットとSkypeで仕事が進んでいくので、週1回、1時間、無理矢理理由を付けて集まってミーティングをしています。

最初はコードレビューをしていたんですが、

「Redmineにコードレビュープラグイン入れたからいらなくね?」

ってことで何でもいいので

“誰もがダウンロードできる、動くプログラム”

を持ち回りで作って発表しようということになりました。そういうのを何て呼んだらいいのかわかりませんが、取りあえず“プログラムプレゼンテーション”ということにしました。

1回目:

cocoa*life – Apple Push Notification Serviceを利用した、iPhone クライアントと、Rubyによるサーバの作成。

Objective-Cがgccでコンパイルできることや、cとかと一緒に使える事や、面白いシンタックスをしてることなんて全然知らなかったのでやりたくなりました。モバイルにもWebアプリが絡むと、俄然興味が湧きます。

2回目:

Talkedbun – 日本語テキストトゥースピーチサーバー – p0t

mac版もフリーになってくれると嬉しいなあ。

やってみて感じたんですが、

  • 他人にダウンロードされて実行される
  • 会社名義じゃなくて自分名義(会社はあくまでリンクをはったりするだけw)

だと逆に大変。

ダウンロード出来る状態だとソースとかごまかしが効かないし、自分名義だと「給料分クオリティ出してりゃいいだろう」という妥協もし辛い・・・。

やってる方としても大変ですが、これは面白い勉強法だなあと思いました。

自己紹介が面倒なのでプロフィールをエントリーにまとめておきます。

プロフィール

名前
駒形 真幸
写真
性別
男性
現住所
東京都渋谷区
出身地
東京都八王子市
生年月日
1978年5月13日
趣味
読書, ゲーム, インターネット, ダイエット
職業
プログラマ
似ている芸能人
  1. 昔の山のフドウ
  2. 大黒シズオ
  3. 牛股権左衛門
生まれ変わったらなりたいもの
  1. 佐藤浩市
  2. M.ナイト.シャマラン
  3. 姜尚中(ハスキーボイス)
好きな本・マンガ
MASTERキートン、団地ともお、血だるま剣法
好きな言葉
焼け石に水
連絡先
    Email:
    komagata@gmail.com
    mixi:
    179970
    Windows live Messenger
    komagata@hotmail.co.jp
    Skype
    komagata1111
    Twitter
    komagata

ドキュメント

p0t
ガチ鬱プログラマー日記
大東亜戦争従軍記
戦争時の祖父の手記をブログ化
ちゃりんちゃりん生活
Webのマネタイズについて
Mr.T
渋谷区本町六号通り商店街にあるMr.Tの謎を追う
アクトインディ技術部隊報告書「komatata」
アクトインディ株式会社在籍時の技術ブログ
ウノウラボ: 検索結果:「komagata」
ウノウ株式会社在籍時の技術ブログ

動画

GemCasts
便利なRubyGems紹介
生放送しながらWebサービスを作る
Help me, hackers!というWebサービスをゆるいおっさん二人が作ります。

サービス

Plnet
フィードアグリゲーションサービス
Mojavi Japan
PHPのWebアプリケーションフレームワークMojaviの各種リソースと日本語コミュニティ

ツール

win32-aques_talk
AquesTalk rubyバインディング
saimaa
継続的インテグレーションを助けるコマンド
Talkedbun
日本語テキストトゥースピーチサーバー
Darjeeling
ちょっと見易いRedmineのテーマ
Cloister
Rails簡単ブログ
DNSBL::Client
荒らし対策DNSブラックリストクライアント
ssl_requirement_paranoid
IEでSSL移動時警告が出ないようにするRailsプラグイン
Widget.Dialog
標準のalert, confirm, promptを置き換えるようなシンプルなJavaScriptライブラリ
AwesomeFramework
PHP4, PHP5(多分6も・・・)対応のとてつもなくシンプルなWebアプリケーションフレームワーク
Raw Template Engine
PHP4, PHP5対応のとてつもなくシンプルなテンプレートエンジン

メディア

イベント・カンファレンス

所属

駒形真幸
個人事業主
FJORD, LLC(合同会社フィヨルド)
代表社員
スペイシーズ
外部取締役

出社

フィヨルド
平日
スペイシーズ
月1

仕事でやってること

  • コード書く
  • サーバー作る
  • BTS書く(Redmine)
  • リリースする(デプロイ)
  • ミーティングする

仕事で作ってるもの

おはようございます。仕事で2年ぐらい、8サイト連続ぐらいでRails使ってるのにあまり上達の見えないkomagataです。

そこで、Railsで不便に思っていること、他人に聞くに聞けないちょっとしたことなどを列記してみたいとおもいます。

  1. namespaceを含むscaffoldが不便。(scaffold Admin::Userとした場合、modelは普通のUserになってほしいが、Admin::Userになる。indexは/admin_users/indexみたいな感じになる。)generator書けば住む話だがめんどい。
  2. controllerのテストはfixtureを使うべきか、mock/stubのみを使うべきか。
  3. 初期データ(マスタなど)の登録はどのようにやるべきか。(今はfixtureとは別にdb/default/*.csvをおいて、migrationファイル内でFixtures.create_fixtures(db/default, users)などのようにしている。
  4. vimの場合、リファクタリングはどうやるのが便利か。(svn管理下ファイルのリネーム、クラス名、メソッド名の一括置換などがめんどい)
  5. ssl_requirementプラグインでのhttpsへのリダイレクトを伴う動きはどうやってテストするのか。
  6. IEでの警告回避のためのhtmlを使ってのhttpsへのリダイレクトを伴う動きはどうやってテストするのか。
  7. 単一テーブル継承を使った場合にいろいろとだるい。
    1. 継承したクラスの必須項目はRDBでnot nullできない(ちょっと気にかかる)
    2. 継承したクラスのbelongs_toとかのカラムがnot nullできない(同上)
    3. 外部キー制約とかが元クラステーブル名になる(あたりまえだけど)
  8. インスタンス変数を前提としたヘルパーを多用してよいのかどうか。(引数以外の値を利用するヘルパー)
  9. helper :allはデフォルトでは無くしてほしい。
  10. erb利用時のpartialなどのインデントがそろわない。
  11. content_for :fooなどを書いた場合、便利だがちょっとテンプレが汚れる感がある。
  12. title, meta_description, meta_keywordsの標準的な各ページでの指定方法はどういうやり方があるのか。
  13. パン屑リストの一般的な実装はどういう感じなのか。
  14. prototype, scriptaculous, RJSが使い辛い。

文句ばっかりですが、上記以外とても気に入っていますし、これがなきゃ開発したくないという要素も数えきれないほどあるのでプラス面の方が全然大きいです。

勉強会などにあまり出席したことがないのでいびつな使い方になってるかもしれません。「ここはこうやればいいよ」などのご指摘があればコメントいただけるとありがたいです。

お客さんにWebサイト作成の進行状況を確認してもらうための環境をBASIC認証をかけて公開することがよくあります。(本番とは別)

しかし、Railsのrestful_authenticationプラグインだとユーザー認証にBASIC認証を使うために、apache側でかけたBASIC認証と二重になってしまってうまくありません。(ユーザー認証がBASIC認証だというのは理に適っていて辞めたくない感じです)

IP制限を使ってましたが、確認してもらうお客さんが複数いたり、IPが一定しないと使い勝手がよくありません。

プロクシなどは一般のお客さんに使ってくれと言うのは厳しいです。

こういうとき皆さんどうしてますか?

追記:

こういう対応になりました・・・。

以前、オリジナルのscaffoldジェネレーターを作るのがびっくりするほど簡単なことを知って、次のプロジェクトを始める時には必ずそれ用のscaffoldを作ってから始めようと思ってました。

プラグインの雛形を作る。名前は適当です。(YetAnotherScaffold)

script/generate plugin ya_scaffold

デフォルトのscaffoldをコピる。(下記の場所はDebianの場合)

mkdir -p vendor/plugins/ya_scaffold/generators
cp -r /usr/lib/ruby/gems/1.8/gems/rails-2.2.2/lib/rails_generator/generators/components/scaffold \
vendor/plugins/ya_scaffold/generators/ya_scaffold

ファイル名とクラス名を変える。

cd vendor/plugins/ya_scaffold/generators/ya_scaffold
mv scaffold_generator.rb ya_scaffold_generator.rb

これだけで同機能、別名のscaffoldジェネレータができる。

script/generate ya_scaffold Foo name:string ...

名前が変わっただけ。

中身を見ると、何を変えたらいいのか一目瞭然なので思う通りに変えられます。ジェネレートされるファイルのテンプレはERBなのでそれを弄るだけでも随分違います。

今回のプロジェクト用に吐かれるHTMLを弄ったり、new, editから共通の_formを使うようにしたり、i18nやpaginate入れたり、scaffold.cssやlayoutを作らないようにしたりと極簡単な変更しかしてないですが、作業の手間はかなり短縮できて嬉しいです。

こんな簡単だったらさっさと試してみればよかった。まことに遺憾です・・・。