トップ «前の日(02-23) 最新 次の日(02-25)» 追記

2005-02-24

_ CLIE 終了ですか

その前に自分の中のちっこい機械好きがなんかどうも終了してるっぽいのですが。

実はポケコンから HP200LX へ行った由緒正しきキーボード付きのちっこい機械好きなのですが、PDA サイズのものに結局魅力を感じなくなって HP200LX 以降はまったく手にしていません。理由のいちばんは

  • 電車移動じゃないから

というものですが、それ以外にも

  • なんだかんだで(キーボードも含めて)フル機能ほしくなっちゃうから、ノート PC の方がいい
  • PC と PDA で違う操作方法(アプリ)を用意して、データをシンクロして、、、って考えるだけで面倒くさい
  • もう少し出せばノート PC 買える値段を投じられるほど余裕がない

という辺り。型落ちモバイルノートをメインマシンにしてしまえば上の3つの問題を全部解決できるのでそうしてます。メインをデスクトップにしてりなざうとかにすればいいじゃんという指摘もあるかもしれないけど、なんかどうもデスクトップの「決まった場所に座らないといけない」という制約がそもそもきらいなのね。きらいなのです。

ということで、そういう使い方をし始めて、、、もう10年経つのか。うわーどーゆーことだーorz

スケジュールとかメモとかは今はもう携帯でいいです。基本的には PC で整理して携帯にメール、携帯でメモして PC にメール、だけで済ましてます。特別なツールは使わず、Wiki からメールに、メールから Wiki にコピペしてるだけ。どうせそんなに大量のデータのやりとりは必要ないから。携帯用フルキーボードが安価に手に入ったらもっとヘビーに使うかもしんないけど、それも最初のうちだけだろうなぁ。

Tags: Tool News
本日のツッコミ(全3件) [ツッコミを入れる]

_ su [全然関係ない話で恐縮ですが、RSS が変です。存在しないリソース(http://f50.aaa.livedoor.j..]

_ wtnabe [すいません。tDiary のクセと私の使い方がうまくかみ合ってない部分がありまして、たまに二重に内容が登録されたり、..]

_ su [そういうことでしたか。最近拝読する様になりましたので、存じませんでした。お手数おかけしました。事情を頭に入れておけば..]


2007-02-24

_ sh づいている日々

高級なスクリプトでも当然書けるんだけど、例えばあるパターンで行を処理してごにょごにょ、とかって処理は結構 awk と組み合わせて sh スクリプトで書いた方がやりやすかったりする。で、ちょっと最近凝った sh スクリプトを書くようになってハマったのが

  1. 引数のチェック
  2. エラーの意味がよく分からん

の辺り。

1 については getopt と case の組み合わせをマスターしないと面倒くさくなりそうなんで、これが今後の課題。*1

2 については xtrace を使ったり verbose にするとよいらしい。つまり起動時に -xv をつける。ただしこれはオリジナル sh のマニュアルがないと気づきにくい。

特に bash のマニュアルはあんまりよくない。bash のマニュアルしか手元にないようなら、set コマンドのところを見る。-o option-name のところに same as -x と書いてあれば、それはコマンドラインオプションの -x と同じだよという意味になっているんだけど、コマンドラインオプションの説明なんか端折りまくりじゃないか。

zsh の場合は man zshoptions の sh/ksh emulation set に書かれている。これはまだ分かりやすい。

というかオリジナルの sh のマニュアルくらい用意しておいてくれよ。

というわけで最近物色していた shell 関係の本は以下の通り。

プロフェショナルシェルプログラミング (Ascii software science―Programming paradigm)(砂原 秀樹)
ASCII の プロフェショナル・シェルプログラミング のページも参考まで。昔からものすごく気になっていたもの。今の自分なら csh についての説明は要らないし、基本的な部分の説明も要らないんだけど、安いしコンパクトだし、名前に反して入門向けとしていいと思う。もし後輩が買おうかどうしようか迷ってるんですと言ってきたら間違いなく薦める。昔のこういう ASCII の本は大好きだ。あ、自分の手元には たのしいUNIX―UNIXへの招待 (Ascii books)(坂本 文)続・たのしいUNIX―シェルへの招待 (Ascii books)(坂本 文) があるんで、スクリプトだけじゃなくてシェル上の操作も含めて基本からっていう話ならこれ貸すかな。
入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界(ブルース ブリン)
とても詳しいし、イチからきっちり勉強したいんですっていう人にはオススメ。上の -xv オプションも書かれている。というかこれ、前の版から絶賛されているらしいのでここに挙げるのは今さらか。
詳解 シェルスクリプト(Arnold Robbins/Nelson H. F. Beebe)
一冊置いてあると絶対安心できると思う。移植性の辺りは他にあまり扱ってる本がないので重宝するかと。
Bash Quick Reference(Arnold Robbins) 
コンパクトにまとまっていてかつ素人が素人向けに書いた Web 上の情報よりはるかに使えると思う。日本で書き下ろされた小さい本よりさらに安い(はずだ)し。なんかいま日本の Amazon には在庫ないし思いっきり bash って書いてあるけど。
Tags: Sysadmin

*1 例えば $2 が存在しているかどうかはいきなり [ $2 ] って書いてもうまく判別できないみたい。しかも標準状態ではエラーメッセージの意味がよく分からない。

本日のツッコミ(全2件) [ツッコミを入れる]

_  [古典ですが、こちらもおすすめです。 http://flex.ee.uec.ac.jp/texi/sh/sh.html..]

_ wtnabe [なるほどありがとうございます。オリジナルっていうのは bourne shell くらいの意味でして、手元では一応 F..]


2009-02-24

_ gem メソッドで gem ライブラリのバージョンを指定

21:07:06 wtnabe< ruby で require 時にバージョン指定することってできない
のかな
22:23:11 ma2> @wtnabe gemを使わないとダメなんじゃないでしょうか。
22:25:20 wtnabe< @ma2 えっと、require_gem でできるってことですか?
22:30:49 wtnabe< あー Kernel#gem か。なるほど。
23:15:35 wtnabe< @ma2 gem 'GEM_NAME', 'version'; require 'GEM_NAME' で
すね。ありがとうございます。
$ ri Kernel#gem
------------------------------------------------------------- Kernel#gem
     gem(gem_name, *version_requirements)
------------------------------------------------------------------------
     Use Kernel#gem to activate a specific version of +gem_name+.
(snip

例えば以下のように mechanzie 0.8.5 と 0.9.2 がインストールされているとします。

$ gem list -a mechanize

*** LOCAL GEMS ***

mechanize (0.9.2, 0.8.5)

普通に require すると当然バージョンは 0.9.2 になりますが、

$ ruby -e '
require "rubygems"
require "mechanize"
puts WWW::Mechanize::VERSION
'
0.9.2

gem メソッドでバージョンを明示するとそのバージョンを使うことができます。

$ ruby -e '
require "rubygems"
gem "mechanize", "0.8.5"
require "mechanize"
puts WWW::Mechanize::VERSION
'
0.8.5

この辺を見ると

RubyGems User Guide | RubyGems Manuals

ある特定バージョンだけでなく、「以降」、「以前」、これらを組み合わせた「範囲」も記述できるようです。なるへそ。

Tags: RubyGems Ruby

2011-02-24

_ 今さらRails3メモ - その5: Model Association -

まずは設計以前の話から。(というか設計は語れません。)

あと、Rails ガイド読むならこのエントリ要らない。

Ruby on Rails Guides: A Guide to Active Record Associations

基本概念

用語

DBMS 用語としては entity の relation だと思うんだけど、Rails 的には クラスベース OOP の用語をそのまま拝借して Model(クラス)の association と呼ぶらしい。

DBMSの制約はただの約束
  • 外部キー制約 = リレーションシップではない
  • DBMS はこの制約を無視して構わない
  • リレーションシップはテーブル設計を開発者が「そう決めた」から

リレーションシップを設定するのが外部キー制約ではないことに注意してください。外部キー制約は、列の値がターゲットテーブルの既知のキーを参照するかどうかチェックすべきことを、データベースに指示するだけです。DBMS は、この制約を無視して構いません(実際に MySQL の一部のバージョンは無視します)。テーブル間リレーションシップが設定されるのは、開発者が product_id 列と order_id 列に products テーブルと orders テーブルのキー値を入力することを決めたからです。

(『RailsによるアジャイルWebアプリケーション開発』第1版 p232)

「要は外部キーでしょ」と分かった気になっていただけでに少なからずショック。

以下、とりとめもなく感想とか。Before Rails な世界の住人としては最近のアプリの DBMS の schema dump とか見ると制約が全然なくてすごくスカスカした感じがするんだけど、DBMS の制約を使うと変更に弱くなるので使わない、という方針なんだよね。逆に Model の中身は制約というか validation がズラッと並んでいて「おぉこれは」という感じになってる。つまり Model の方に注目しなきゃいけない。だから Model を利用したうえで ER 図っぽく起こしてくれる

Rails ERD &#8211; Entity-Relationship Diagrams for Rails

みたいな道具は必須だなと感じた。こういうのなかった時代はどうしてたんだろう、ほんと。素朴な ER 図作成ツールとか使っても実態と合わないわけでしょ?

key と id
  • ActiveRecord のデフォルトルールでは primary key は `id' 列(自動でセットされる)

attribute 上では変更は可能。

class Model < ActiveRecord::Base
  set_primary_key "code"
end

ってやったら attribute 上は code が primary key になる。ただし migaration の方もいじっておかないと DBMS 上では id のまま。のはず。一応確認したけど間違ってたらごめん。

  • 同じく外部キー列の名前は #{table}_id

これも

class Model < ActiveRecord::Base
  belongs_to :foo, :foreign_key => 'foreign_key'
end

のように association の option で変更できる。

基本的なAssociation

  • belongs_to
  • has_one
  • has_many

基本的には Rails ガイドを読めば分かる。なめちゃいけない、すごく丁寧。

中でも belongs_to を忘れると話にならないのでとりあえずこれだけ。

class Model < ActiveRecord::Base
  belongs_to :table
end

そして自分の所属する table の id ( primary_key ) を保持するカラムを作る migration を用意する。

class AddForeignkeyToModel < ActiveRecord::Migration
  def self.up
    add_column( :models, :table_id )
  end

  def self.down
    remove_column( :models, :table_id )
  end
end

こんな感じ。

この部分は自然な読みやすさを重視してるらしく、has_many だと

class Model < ActiveRecord::Base
  has_many :tables
end

になったりする。自然かもしれないけど、決まってないと不安な気もしないではない。

オプションもいっぱいある。

Module: ActiveRecord::Associations::ClassMethods

先に挙げた foreign key の他にもいろいろ。

応用Association

  • has_and_belongs_to_many
  • has_many , :through =>
  • has_one, :through =>
  • belongs_to , :polymorphic => true
has_and_belongs_to_many

Module: ActiveRecord::Associations::ClassMethods

いわゆる 多:多, M:N と呼ばれる関連を表現する。has_and_belongs_to を相互に書くことで結合テーブルを隠蔽した多:多の association を定義できる。

※ 素朴な話をすると 多:多 っていう relation は存在しなくて、実際この association も隠蔽されているだけで結合テーブルを利用する。DBMS の基本が分かっているなら 多:多 も特別怖がる必要はない。あくまで ORM は DBMS の使い勝手をよくするもので DBMS の機能に変化はない。

具体的には

Foo < Model
  has_and_belongs_to_many :bars
end

Bar < Model
  has_and_belongs_to_many :foos
end

と定義すると

foos_bars

という結合テーブルを使って相互に更新される。migration は以下の通り。

class FoosBars < ActiveRecord::Migration
  def self.up
    create_table :foos do |t|
      ...
    end

    create_table :bars do |t|
      ...
    end

    create_table :foos_bars, :id => false do |t|
      t.column :foo_id, :integer, :null => false
      t.column :bar_id, :integer, :null => false
    end
  end

  def self.down
    drop_table :foos
    drop_table :bars
    drop_table :foos_bars
  end
end

primary key を持たない(should not have)結合テーブル を手動で migration して作らなければならない(you must manually generate)。

この場合、結合テーブルに該当するモデルは定義する必要がない。言い換えると結合テーブルを操作することはできない。

class Foo
  bars.push_with_attributes( barのレコードオブジェクト, column symbol => 値 )
end

という形で参照先のテーブルを更新する。

has_(one|many), :through =>

結合テーブルを利用した association に独自の何かが欲しい場合もある。先ほど隠蔽した 多:多 の association を表現する Model を定義し直すと以下のようになる。

class Foo < Model
  has_many :bar, :through => :foo_bar
end

class Bar < Model
  has_many :foo, :through => :foo_bar
end

FooBar < Model
  belongs_to :foo (, :dependent => :destroy )
  belongs_to :bar (, :dependent => :destroy )
end

明示的な Model を作ると独自の処理を自然に記述しやすくなるし、明確な意味を持たせやすい。

上の例では結合テーブルのような名前になっているが、当然名前も自由に決められる。このテーブルの意味が明確になる名前に設定するとよい。

Polymorphic

Model の関係を固定せず、似た association を複数実現する機能。仮想のテーブルをここでは :polymorphable とした場合に具体的に Model 上の記述では

Foo < Model
  belongs_to :POLYMORPHABLE, :polymorphic => true
end

Bar < Model
  has_XXX :foo, :as => :POLYMORPHABLE
end

の組み合わせで実現する。

この際、migration では

create_table :foos do |t|
  t.references, :POLYMORPHABLE, :polymorphic => true
end

と定義する。実際にはこれは

create_table :foos do |t|
  t.string,  :POLYMORPHABLE_type
  t.integer, :POLYMORPHABLE_id
end

という形に展開される。大文字の POLYMORPHABLE はもちろん小文字で。

※ この部分には名詞ではなく形容詞の -able にするのがパターンとして多いみたいだけど、明確な理由は分からない。恐らく複数形への変化の影響を受けないとか :as => -able が自然に読めるとかそういうことだと思う。

特徴は

  • belongs_to では物理的なテーブル名ではなく、仮想のテーブル名を指定し、:polymorphic => true を付加
  • has 側では物理的なテーブル名を指定するが :as を使って仮想のテーブル名も指定する
  • belongs_to 側の table のカラムには has な table 名は直接入らない
    • (ここまでに登場した association では bar_id というカラムがあるはず。)
  • belongs_to 側の table は has 側の Model 名を #{POLYMORPHABLE}_type に格納する
    • ここで Model 名が可変になっているので association を柔軟に変更できる

よく例に挙がるのは画像を格納するテーブルを Polymorphic で紐づける方法。例えば RSS 2.0 などでは blog そのもの、entry それぞれなどに画像を指定できるし、その数も決まっていない。したがって

class Blog < Model
  has_one :image, :as => :imagable
end

class Entry < Model
  has_many   :images, :as => :imagable
  belongs_to :blog
end

class Image < Model
  belongs_to :imagable, :polymorphic => true
end

のように関係を記述できる。この場合、

  • :imagable_type に 'Blog' か 'Entry' が入る
  • :imagable_id にそれぞれの Model の id が収まる

ことで複数の Model に belongs_to することができる。若干分かりにくいがとても便利。

上の例の Entry のインスタンスで .images を呼ぶと :image テーブルから自身に紐づいているレコードを取得できる。以下のような感じ。

entry = Entry.find(params[:id])
entry.images
単一テーブル継承との組み合わせに注意

あまりこんなことはやらないかもしれないけど。

  • Polymorphic で使われる Model クラス名は DBMS のテーブルに紐づくクラス名
  • 単一テーブル継承の子どものクラス名を格納してしまうと検索できない

ので注意。

参考

Tags: Rails Ruby