投稿者 okkez
2010-07-12 12:43:00 GMT
日曜日に「リファクタリング Ruby エディション」読書会の第二回に行ってきた。
二章から六章の途中まで読んだ。
二章から五障まではオリジナルのリファクタリングとあまり違いが無かった。
六章からリファクタリングのカタログが始まる。まだいくつかの節しか読んでいないが、参考になることも多いけど、
知っていることの方が多い。
でも、間違ったことも色々と書いてあるので、読みこなすには中級以上の知識が必要だと思った。
カテゴリ Ruby | タグ Ruby | コメントなし | トラックバックなし
投稿者 okkez
2010-05-31 14:40:00 GMT
リファクタリングRubyエディションの読書会に行ってきた。
まだ第一章しか読んでいないけど、一章は間違いが多すぎる。
まず、サンプルで紹介されているコードが徹頭徹尾動かない。一回も実行していないレベル。
動かない部分を直して、GitHub にアップしました。
他の勉強用のコードも混じってるけど、本の流れに沿ってリファクタリングして最低限動くようにした。
ログメッセージが全部 refactor になってるのはご愛嬌です。
第一章は残念な感じでしたが、二章以降に期待したいところです。
カテゴリ Ruby | タグ Ruby | コメントなし | トラックバックなし
投稿者 okkez
2010-05-25 13:53:00 GMT
HikiDoc - FrontPage.ja でプラグインを使いたかったので、プラグインを作る方法を調べてみた。
ソースを読めばプラグインを作る方法はわかる。
しかし、HikiDoc を使った上でプラグインも使っている例はあまりないようだった。
class CustomOutput < HikiDoc::HTMLOutput
def initialize(suffix = " />", options = {})
super suffix
@options = options
end
def inline_plugin(src)
# あんまり使わないので未実装
end
def block_plugin(src)
name, *args = parse_plugin(src)
klass = Plugins.const_get(name.classify)
@f.puts klass.new(@options).call(args)
rescue NameError => ex
@f.puts ex.message
end
private
def parse_plugin(src)
result = []
if /([a-z0-9_]+)\((.+)\)/m =~ src
result.push $1
result.push *$2.split(',').map(&:strip) if $2
end
result
end
end
こんな感じで HikiDoc::HTMLOutput を継承して inline_plugin と block_plugin を定義すれば良い。
今回の実装方法でプラグインを定義するには以下のようにする。
Rails で使用するのでヘルパーを使えるようにしておく。
module Plugins
end
class Plugins::Base
include ActionView::Helpers, ::ERB::Util
def initialize(options = {})
@options = options
end
def call(args)
raise 'must implement in subclass'
end
end
class Plugins::Echo < Plugin::Base
def call(args)
%Q!<pre>#{args.inspect}</pre>!
end
end
クラスを使わずに実装する方法もあるが、今回は Rails なので Rails っぽくなるようにクラスを使ってみた。
クラスを使わない場合は、プラグインの名前をキーにしたハッシュに処理を登録する方法が使えると思う。
Hiki では HikiDoc のプラグイン機構は使っていないように見えたけど気のせい?また今度調べてみる。
カテゴリ Ruby | タグ Rails, Ruby | コメントなし | トラックバックなし
投稿者 okkez
2010-05-25 13:17:00 GMT
ryanb’s cancan at master - GitHub を使ってみた。
元々 be9’s acl9 at master - GitHub を使っていたのだけど、
ちょっと手の込んだことをやろうとすると、やり方がわからなくなったので cancan を使うことにした。
Rails Authorization in The Ruby Toolbox でも人気だったし @kakutani にも紹介してもらったし。
ほとんどのことは Home - cancan - GitHub の Wiki を見ればわかる。これで分からない場合は rdoc.info :: cancan を見ればいいはず。
acl9 に比べていいところは
- 権限に関するコードが一ヶ所に書けるところ
- 権限だけのテストを簡単に書けるところ
- 複雑な権限管理もそれなりにシンプルに書けるところ
- たぶん DB に権限情報を書いてそれを読み込むように書いても使えるところ
良くないところは、権限のコードが長くなってしまうことくらい。
これはテストを書けば、特に問題にはならないかもしれない。
あるいは DB に権限データを登録するようにしてしまえば、シンプルになるだろう。
カテゴリ Ruby | タグ Rails, Ruby | コメントなし | トラックバックなし
投稿者 okkez
2010-05-25 13:00:00 GMT
thoughtbot’s paperclip at master - GitHub を使ってみた。
あるモデルにカラムを追加して使う方法の場合は Home - paperclip - GitHub をよく読んで使えば問題なさそうだった。
一つのレコードに複数の添付ファイルを持たせる場合に少しハマったので書いておく。
class Issue < ActiveRecord::Base
has_many :attachments, :class_name => "::Attachment", :dependent => :destroy
end
class Attachment < ActiveRecord::Base
belongs_to :issue
has_attached_file :attachment
end
このようなクラス構成の場合、Attachment というモデルは paperclip で定義している Paperclip::Attachment と名前が
被るので Issue の定義で注意する必要がある。
上で書いているように、:class_name オプションに「フルパス」でモデルのクラス名を書いておけば良い。
あと paperclip では xxx_{file_name,content_type,file_size,updated_at} というカラムを用意すると、
モデルに xxx という名前のメソッドが定義されるので xxx の部分を長くしすぎるとちょっとコードが読みづらくなる。
実際に Attachment モデルに attachment_* という名前でカラムを用意したので以下のようなコードが頻出して気持ち悪くなったことがある。
link_to @attachment.attachment_file_name, @attachment.attachment.url
Attachment クラスでエイリアスを定義しておけば多少はマシになるかと思う。
カテゴリ Ruby | タグ Rails, Ruby | コメントなし | トラックバックなし
投稿者 okkez
2010-03-29 13:15:00 GMT
タイトルは適当。
Rails とか sinatra の tilt っぽい感じでレイアウトファイルに yield って書けるようにする方法がわかった。
レイアウトファイル。layout.html.erb
<html>
<head></head>
<body>
<%= yield %>
</body>
</html>
読み込むテンプレート。body.html.erb
コード。template.rb
require 'erb'
class Template
def initialize()
erb = ERB.new(File.read('layout.html.erb'), nil, '-')
erb.def_method(self.class, 'layout', 'layout.html.erb')
erb = ERB.new(File.read('body.html.erb'), nil, '-')
erb.def_method(self.class, 'body', 'body.html.erb')
end
def render
layout{ body }
end
end
puts Template.new.render
Template#initialize の引数を追加したりすればもう少し汎用的になると思う。
ERB#def_method の第二引数はメソッド名なのでメソッド名として使える文字列を指定しなければならない。
追記
以下のようにすると Rails の動作に少し近くなるはず。
class Template
def render
str = body()
layout{ str }
end
end
カテゴリ Ruby | タグ Ruby | コメントなし | トラックバックなし
投稿者 okkez
2010-02-20 02:00:00 GMT
最近 Rails で作っているウェブアプリケーションでは jQuery を使うようにしている。
なんとなくこうすれば良さそう、というのがわかってきたので書いておく。
google の jsapi を使う。
どこかのブログで見つけたコード片をちょっと変更したやつ。
module ApplicationHelper
def google_jsapi_tag
'<script type="text/javascript" src="http://www.google.com/jsapi"></script>'
end
def google_load_tag(name, version)
%Q|<script type="text/javascript">google.load("#{name}", "#{version}");</script>|
end
end
layout では以下のようにする。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<%= google_jsapi_tag %>
<%= google_load_tag 'jquery', '1.3' %>
<%= google_load_tag 'jqueryui', '1.7' %>
<%= javascript_include_tag 'application' %>
<%= yield :head %>
<%- javascript_tag do -%>
jQuery(function($){
if (navigator.cookieEnabled) {
$("#cookie_check").hide();
} else {
$("#cookie_check").show();
}
<%= yield :script %>
});
<%- end -%>
<%= stylesheet_link_tag 'application' %>
<%= stylesheet_link_tag 'jquery-ui-1.7.2.custom' %>
<title><%= @title %></title>
</head>
<body>
<!-- 略 -->
</body>
</html>
こうしておくと view では以下のように書くことができる。
<%- content_for :script do -%>
$("a#hoge").click(function(event){ /* なんか処理 */});
<%- end -%>
global な名前空間を汚さないし、割と短く書けるし気に入っている。
カテゴリ Ruby, 雑記 | タグ javascript, jquery, Rails, Ruby | コメントなし | トラックバックなし
投稿者 okkez
2010-02-12 04:00:00 GMT
prawn を Rails2.3.5 で使おうと思って調べてみたら、prawnto が使えなくなっていた。
仕方が無いので prawn 単体を Rails で使う方法を考えてみたので書いておく。
以下のコードをそれぞれのファイルに書く。
# config/environment.rb
config.gem "prawn"
config.gem "prawn-layout", :lib => "prawn/layout"
config.gem "prawn-security", :lib => "prawn/security"
config.gem “prawn” だけだと prawn/{layout,security} がちゃんと読み込まれないので別の場所で require する必要がある。
# config/initializers/mime_types.rb
Mime::Type.register "application/pdf", :pdf
# 適当なヘルパー
def render_pdf
pdf = Prawn::Document.new(:page_size => "A4")
# フォントは環境に合わせる
pdf.font "/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf"
yield pdf
pdf.render
end
以上を追加したら、割と簡単に PDF を出力することができるようになる。
コントローラーでこんな風に書いて、
class ReportsController < ApplicationController
def show
@report = Report.find(params[:id]
respond_to do |format|
format.html # show.html.erb
format.pdf # show.pdf.erb
end
end
end
ビューでこう書けばよい。
# show.pdf.erb
<%=
render_pdf do |pdf|
pdf.text "Hello, PDF world!"
end
%>
追記
本家(github)をよく見たら別の方法が書いてあった。
* Using Prawn in Rails - prawn - GitHub
どっちが良い方法なんだろう。
github に書いてある方法だとちゃんとダウンロードするファイル名を指定できるのが良い。
自分が書いた方法だと、view なので view で使用するデータの受け渡しが楽だけどファイル名の指定とかが面倒。
あと Emacs で適切なモードになってくれないのが気にくわない。
カテゴリ Ruby | タグ Rails, Ruby | 2 comments | トラックバックなし
投稿者 okkez
2009-12-18 13:32:00 GMT
この記事は Ruby Advent Calendar jp: 2009 : ATND の 18 日目です。前日は @tad さん でした。
愛用しているものの一つに るりま があります。
みなさんはもうお使いですか?
まだの人は以下の説明を読んでぜひ使ってみてください。
利用方法はいくつかあるので順番に紹介していきます。
web ブラウザを使って見る方法
http://doc.okkez.net/ にアクセスします。3 カラムになっていて左から順番に、BitClust, Static HTML, Download となっています。BitClust はるりまプロジェクトで作ったリファレンスマニュアルを見るためのウェブアプリケーションです。
doc.okkez.net では nginx + thin で動かしています。nginx がキャッシュするようにしているのでまあまあの速さで動くと思います。
Static HTML はあらかじめプログラムで生成した HTML ファイルを置いています。ウェブアプリケーション版とは少しレイアウトが異なりますが内容は同じです。参照したいクラスやメソッドが既に決まっている場合に使うと高速に参照することができます。ウェブブラウザのページ内検索機能を使用すると快適に閲覧できるでしょう。
Download は月一回肉の日(毎月29日)に作成したスナップショットを置いています。http://www.ruby-lang.org/ja/man/archive/ にも同じものを置かせていただいています。
ダウンロードしたアーカイブを使用する方法
- http://www.ruby-lang.org/ja/man/archive/
- http://doc.okkez.net/archives/
どちらかから、ダウンロードしたアーカイブを適当な場所に展開します。
アーカイブの中には以下のようなものがあります。
- bitclust/ ライブラリ
- db-1_8_7/ Ruby1.8.7 向けのデータベース
- db-1_9_1/ Ruby1.9.1 向けのデータベース
- readme.html このアーカイブの説明
- refe-1_8_7 Ruby1.8.7向けの refe
- refe-1_8_7.cmd Windows 用の Ruby1.8.7 向けの refe
- refe-1_9_1 Ruby1.9.1 向けの refe
- refe-1_9_1.cmd Windows 用の Ruby1.9.1 向けの refe
- server.exe Windows 用の実行ファイル
- server.exy server.exe を作るための exerb のレシピファイル
- server.rb *nix などで使用するスクリプト
データベースというのは、指定したバージョン向けに前処理を施したテキストファイル群のことです。
このディレクトリにパスを通して使うのが一番簡単ですが、適当なスクリプトを書いたりするのもいいでしょう。例えば、以下のような感じで書くといいのではないでしょうか。
#! /bin/sh
DOC_BASE=$HOME/ruby-refm
exec ruby -Ke -I $DOC_BASE/bitclust/lib bitclust/bin/refe.rb -d $DOC_BASE/db-1_8_7 "$@"
Windows な人は *.cmd を参考にしてバッチファイルを書くといいのではないでしょうか。
また server.exe というファイルがありますが、Windows を使っている人はこれをダブルクリックすると、ローカルで web server が起動して、自動的にウェブブラウザが起動してリファレンスマニュアルを表示します。ローカルで動いているのでネットワークにつながっていないときでも使用できます。
ダウンロードした chm ファイルを使う方法
- http://www.ruby-lang.org/ja/man/archive/
- http://doc.okkez.net/archives/
先ほどと同様に、ダウンロードします。 chm はバージョン別になっているので自分が使いたい方をダウンロードすればいいでしょう。1.8.7, 1.9.1 以外のバージョンを使いたい人は、自分で chm ファイルを作るといいでしょう。(ここでは説明しません)
Windows Vista 以降の人は、ダウンロードしたファイルをダブルクリックしたときに出てくる警告ダイアログのチェックボックスを外すとちゃんと見られるはずです。
Windows を使っていない人はそれぞれ自分の好きな chm viewer をインストールして使ってください。意外と色々あります。
まとめ
個人的におすすめなのはコマンドラインから使用する refe です。すごく速いです。
とりあえず使ってみてください。古いリファレンスには書いていないこともたくさん書いてあります。
足りない部分はありますが、古いリファレンスよりはかなり進化しています。使わないと損です。
そして、使ってフィードバックをください。みなさんのご協力をお待ちしています。
明日は、たこ焼き仮面の中の人ではないかと噂されているあの人が書きます!
カテゴリ Ruby | タグ るりま, Ruby | コメントなし | トラックバックなし
投稿者 okkez
2009-12-18 14:39:00 GMT
自分で Rails の generator gem のテストを書いてみたんだけど、どうもしっくり来ない。
参考にしたのはここ。
作ってた engines はこれ。
やりたかったことは以下のとおり。
- Rails Engines なので基本的には Rails アプリケーションとしてテストしたい
- generator は engines として使うときに必要なファイルを生成するためのものなので独立してテストしたい
- rake test でちゃんとテスト出来れば OK
で、冒頭の Rails Guides を参考にテストを書いてみたけどちゃんと動かなかったので Rails のソースを読んでみた。
読んでみて分かったのは以下のこと。
- Rails::Generator::Scripts::Generate#run でファイルを生成する先は指定できる
- けど、generator をどこから探してくるかは指定できない
- RAILS_ROOT が定義されていると RAILS_ROOT/lib/generators や RAILS_ROOT/vendor/generators などから探してくれる
- 他には既にインストール済みの generator からも探してくれる
- RAILS_ROOT/generators は見てくれない
作っているのは engines gem なのだから RAILS_ROOT/generators も見てほしいんだけど、それはやってないらしいので、ここでは RAILS_ROOT/lib/generators に symlink を張ることにした。
一応、これでちゃんと動いているみたいなのだけど、setup で symlink 作成して teardown で symlink を削除したりしてるのがちょっと気持ち悪い。
Rails Guides にも書いてあったとおり generator を提供している多くの Gem は generator 自体のテストは書いていない。(cucumber や rspec を参考にしたかったんだけど書いてなかった。)
もう一回やりたかったことをまとめるとこうなる。
- Rails Engines なので基本的には Rails アプリケーションとしてテストしたい
- generator は engines として使うときに必要なファイルを生成するためのものなので独立してテストしたい
- 既存の generator を読み込まずにテストしたい (開発中の Gem と同名の Gem が入っていてもいいように)
- rake test でちゃんとテスト出来れば OK
あ、コードは github に全部上がっているので見てください。
みんな generator のテストはあんまり書かないものなのかなぁ?
カテゴリ Programming, Ruby | タグ Rails, Ruby | コメントなし | トラックバックなし