ひさびさにRailsをやる
ちょっと卒論で作ろうと思ってるシステムをRailsで作りたいなぁと思ってひさびさにRailsをやる。
題材は[Ruby][Rails] Ruby on RailsでWiki
http://d.hatena.ne.jp/muscovyduck/20060511#1147307789
以下少し違ったところと要点をまとめる。
開発&実行環境
walf443@ruribita:railswiki% script/about
About your application's environment
Ruby version 1.8.2 (i386-linux)
RubyGems version 0.8.11
Rails version 1.1.2
Active Record version 1.14.2
Action Pack version 1.12.1
Action Web Service version 1.1.2
Action Mailer version 1.2.1
Active Support version 1.3.1
Application root /home/walf443/railswiki
Environment development
Database adapter mysql
Database schema version 2
データベース周り
自分はMySQL4.0を使った。
後々FrontPageがないとハマることになるので、自分はマイグレーションのスキーマを更に次のように変更した。
# db/migrate/002_initial_schema.rb class Contents < ActiveRecord::Base end class InitialSchema < ActiveRecord::Migration def self.up Contents.create :title => 'FrontPage', :body => 'This is FrontPage.' end def self.down frontpage = Contents.find_by_title 'FrontPage' frontpage.destroy end end
Contentsのアイテムを作成するので事前にクラスだけ定義しておくのがポイント。
$rake migrate
でスキーマを上げたり戻したり出来るのでファイルは分けておいた方が良いと思われる。
self.upメソッドには今回追加する処理を記述。self.downメソッドには前回のスキーマに戻すためのメソッドを記述する。
Helper
Helperにはscript/generate helperとかないのかな。うまく動作しなかった。
題材のページでは一つのファイルにHelperを記述しているけど、こちらでは動かず。ということで以下のようにした。
walf443@ruribita:railswiki% cat app/helpers/railswiki_helper.rb module RailswikiHelper end walf443@ruribita:railswiki% cat app/helpers/railswiki_helper/to_html_with_links.rb require 'rdoc/markup/simple_markup' require 'rdoc/markup/simple_markup/to_html' module RailswikiHelper class ToHtmlWithLinks < SM::ToHtml def handle_special_WIKIWORD(special) %Q|<a href="/railswiki/show/#{special.text}">#{special.text}</a>| end def handle_special_HTTP(special) %Q|<a href="#{special.text}">#{special.text}</a>| end def handle_special_BRACKET(special) %Q|<a href="/railswiki/show/#{special.text[2..-3]}">#{special.text[2..3]}</a>| end end end walf443@ruribita:railswiki% cat app/helpers/railswiki_helper/railswiki_template.rb require 'rdoc/markup/simple_markup' require 'rdoc/markup/simple_markup/to_html' module RailswikiHelper class RailswikiTemplate def initialize(view=nil) @view = view end def render(template, assigns) markup = SM::SimpleMarkup.new markup.add_special /\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD markup.add_special %r|(https?://\s+)|, :HTTP markup.add_special /(\[\[.+?\]\])/, :BRACKET markup.convert template, ToHtmlWithLinks.new end end end
SM::Simpleがなかなか認識されない(Const missing)ので仕方なく両方のファイルにrequireした。こういうときはどこにrequireするものなのだろうか。
Controller・View
hoge :action => ... とかいう感じのメソッドってどちらかというとSymbolを渡したくなるのは自分だけだろうか。特に:actionはメソッド名を指しているのでSymbolの方がそれっぽい気がする。エディタ的には色がつかないので文字列の方が見やすいのだけど。
その他
WEBrickでサーバを起動したとき、.irbrcでプロンプトの設定をしているとActiveSupportの拡張によりエラーが発生するようです。具体的には以下のような記述。
IRB.conf[:PROMPT][:SIMPLEST] = { :PROMPT_I => "", :PROMPT_S => "", :PROMPT_C => "", :RETURN => " #=> %s\n\n" }
エラーメッセージを頼りにunless IRB.conf[:PROMPT].nil? .. end で囲むと大丈夫になった。
まとめ
簡単にできると思っていたが割といろんな場面でハマった。というわけで色々作りながら覚えていこうかと思う。
?表現
[ruby-list:42301]によると文字コードを調べるリテラルだそうです。こんなのあるとは知らなかった…。
マニュアルを引いてみました。
?a
文字aのコード(97)ruby 1.7 feature: 空白類を指定する場合は、?\s, ?\t などとする必要があります。
?\C-a
コントロール a のコード(1)?\M-a
メタ a のコード(225)?\M-\C-a
メタ-コントロール a のコード(129)
irbなどでちょっと確認したいときやキーコード判定をしたいときなどに良さそうです。ただ文字列の文字すべてをコードに直すなど動的に処理したいとき*1や日本語などの文字に関しては使えないのでそれほど使う機会はないかもしれません。
それにしてもruby-listのメールの数はphp-usersなどに比べると非常に少ないのですが、それはRubyの体系がうまく整理されていることとか、多少分からなくてもirbに打ち込んでみればどんな風に動くか手軽に調べられることが関係しているのかなぁと思いました。とはいえruby-talkは非常に数が多いけど。
*1:もちろんevalを使えば出来るでしょう
パスカルの三角形
コメント欄にてあいさんより質問を頂いたので挑戦してみました。
あい 『ちょっと質問なんですが、
パスカルの三角形で、
- -
m 0 1 2 3 4 ・・・
n
0 1
1 1 1
2 1 2
3 1 3 3 1
4 1 4 6 4 1
・
・
・
- -
P(n,m)を求める関数を作るとき
schemeでどう書いたらいいですか?
例えば
(P 4 2)
=6
みたいになるプログラムを作りたいんです。From: http://d.hatena.ne.jp/walf443/20060512/1147448853#c1148982927
どうやったら良いか思いつかないのでid:hyukiさんのコード
http://sicp.g.hatena.ne.jp/hyuki/20060512/pascal
を参考にしてみる。
combinationとlineの定義はそのまま使えそう。。。
まずはn個までパスカルの三角形を求める関数を作成します。
(define (pascal n) (define (pascal-iter i n) (cond ((< i n) (display (line i)) (newline) (pascal-iter (+ i 1) n)))) (pascal-iter 0 n)) (pascal 10) (1) (1 1) (1 2 1) (1 3 3 1) (1 4 6 4 1) (1 5 10 10 5 1) (1 6 15 20 15 6 1) (1 7 21 35 35 21 7 1) (1 8 28 56 70 56 28 8 1) (1 9 36 84 126 126 84 36 9 1)
ここまでやってみてcombinationの定義を眺めていると、ようやくパスカルの三角形は2項係数で表せたことを思い出した。よく考えてみるとcombinationというのは組み合わせという意味だ。(ってそのまんま)
ということで、
(define (P n m) (cond ((= k 0) 1) ((= k n) 1) (else (+ (P (- n 1) k) (P (- n 1) (- k 1))))))
要するにを定義すればよいようです。
階乗を定義してやるとより分かりやすく書けそう。
(define (combination n k) (define (factorial x) (if (= x 0) 1 (* x (factorial (- x 1))))) (/ (factorial n) (* (factorial k) (factorial (- n k)))))
反復を使っていないのでかなり直感的。
しかしなので、
(define (combination n k) (define (fact-iter init last) (if (= init last) last (* init (fact-iter (+ init 1) last)))) (/ (fact-iter k n) (fact-iter 1 (- n k))))
とも書ける。反復使っているし余計なものを約分してるのでこちらの方が効率よさそう。
とここまで書いてid:hyukiさんのコメント欄を見ると全く同じメッセージがっ!!もしかしてスパム?まぁ、いいや勉強になったし…。