3 日坊主日記
2007-01-02 [長年日記]
_ Rel
Rel。Tutorial DのJava実装。
- http://shark.armchair.mb.ca/~dave/relforum/viewtopic.php?t=11
- http://shark.armchair.mb.ca/~dave/Rel/84kbps.wmv
インタビュー。13:55辺りでちらっとRubyが出てくる。
Tutorial D
- http://en.wikipedia.org/wiki/D4_%28programming_language%29
- http://www.alphora.com/docs/DataphorSet.html
D4。Tutorial DのC#実装。
_ ruby-refm phase 2: tk tkextlib
作業量の少ない moriq です。
ruby-1.8.1/ext/tk で rdoc --ri。
はうあ。
1.8.2以降はTkディレクトリの中に入るので構造が違うんだけど@sinceはこの辺考慮するんだろうか。するんだろうなあ。
_ ruby-refm phase 2: tk tkextlib (3)
わかった。 ext/tk じゃなくて ext/tk/lib で作れば ok。
明らかに多い。
追記: 見苦しいのでファイルに追い出しました。
2007-01-03 [長年日記]
_ ruby-refm phase 2: tk tkextlib (4)
tkextlib/blt/component.rb: module Tk::BLT module Tk::BLT::PlotComponent module Tk::BLT::PlotComponent::OptKeys class Tk::BLT::PlotComponent::Axis class Tk::BLT::PlotComponent::Crosshairs class Tk::BLT::PlotComponent::Element class Tk::BLT::PlotComponent::Bar class Tk::BLT::PlotComponent::Line class Tk::BLT::PlotComponent::GridLine class Tk::BLT::PlotComponent::Legend class Tk::BLT::PlotComponent::Pen class Tk::BLT::PlotComponent::Postscript class Tk::BLT::PlotComponent::Marker class Tk::BLT::PlotComponent::TextMarker class Tk::BLT::PlotComponent::LineMarker class Tk::BLT::PlotComponent::BitmapMarker class Tk::BLT::PlotComponent::ImageMarker class Tk::BLT::PlotComponent::PolygonMarker class Tk::BLT::PlotComponent::WindowMarker
たくさんあるなあ。
むう。本文は誰が書くんだろう…
2007-01-04 [長年日記]
_ ruby-refm phase 2: 特異クラス定義をうまく読めない (win32 ri)
調子よく変換していたのだが
# tkextlib/blt/winop.rb:-
require 'tk'
require 'tkextlib/blt.rb'
module Tk::BLT
module Winop
extend TkCore
TkCommandNames = ['::blt::winop'.freeze].freeze
end
WinOp = Winop
end
class << Tk::BLT::Winop
def changes(win)
tk_call('::blt::winop', 'changes', win)
end
...
end
こういう特異クラス定義を ri が読めてないなあ。
ruby -v ruby 1.8.5 (2006-08-25) [i386-mswin32]
cd c:\tmp rdoc --ri --op ri c:\arc\ruby-1.8.5-p12\ext\tk\lib ri -d c:\tmp\ri\ri Tk::BLT::Winop (特異クラス中のメソッドが出ない)
どうしたものか。
(win32 で rdoc --ri するとなぜか --op のディレクトリが2重になる)
追記:
ruby 1.8.5 (2006-12-25 patchlevel 12) [i686-linux]
でも同じだった。
追記: わかった。module として定義してから class << ほげ した場合うまくいかないようだ。
@methods を full_name で検索するメソッドがないみたいなので find_symbol を使ってみた。うまくいったように見える。
2007-01-18 [長年日記]
_ [Rails] where plugin の Cond を Rio 的な遅延評価で書けたら
ActiveRecord で
S.find(:all, :conditions => ["city = ?", "Paris"])
を
S.find(:all).select { |s| s.city == "Paris" }
と書くと、速度・メモリに深刻なダメージを受けるけど、 where plugin の Cond を Rio 的な遅延評価で書けたら
S.select { |s| s.city == "Paris" }.find(:all)
と書けて嬉しいかも。
select の alias として conditions, where, restrict 辺りを用意。
&& -> Rel.and (Rel#& ??) || -> Rel.or (Rel#| ??) ! -> Rel.not
:select option -> Rel.project("city")
:joins, :include option -> Rel.join("S", "P")
また、ActiveRecord と SQL (RDBMS) の間に何かがあるとすれば、こういうことは当然できるに違いない。
_ scoped_access
class UserMemoController < MemoController
scoped_access Memo, :restricted
protected
def restricted
ScopedAccess::MethodScoping.new(:user_id => session[:user].id)
end
end
memo_rel = Memo
user_memo_rel = Memo.select { |m| Rel.theta("=", m.user_id, session[:user].id) }
...
user_memo_rel.find(:all)
_ acts_as_view
class Member < ActiveRecord::Base; end
class ActiveMember < Member acts_as_view :deleted => false end
class InheritedActiveGrade2Member < ActiveMember acts_as_view :grade=>2 end
member_rel = Member
active_member_rel = member_rel.select { |m| Rel.theta("=", m.deleted, false) }
active_grade2_member_rel = active_member_rel.select { |m| Rel.theta("=", m.grade, 2) }
_ [Rails] Tagged Rails 1.2.0
キター
2007-01-20 [長年日記]
_ [Rails] 次回から自動でログインする
<%= check_box_tag "auto" %>
何かしらチェックしたときには
ActionController::Base.session_options[:session_expires] = Time.now + 1.month
セッションを長期間有効にする。
チェックしないときには
ActionController::Base.session_options[:session_expires] = nil
セッションはブラウザを閉じるまで有効 (デフォルト)。
これが単純には実現できない。
class XController
def authenticate
auto = params[:auto]
# これは無効
request.session_options[:session_expires] = auto ? Time.now + 1.month : nil
session_options はいつ反映される? session を用意するとき (初めて session にアクセスしたとき)。
session はどこで用意される?
action_controller/cgi_process.rb:
module ActionController
class CgiRequest < AbstractRequest
def session
unless defined?(@session)
...
@session = CGI::Session.new(@cgi, session_options_with_string_keys)
CGI::Session って何?
lib/ruby/1.8/cgi/session.rb:
class CGI
class Session
def initialize(request, option={})
request.instance_eval do
@output_hidden = {session_key => session_id} unless option['no_hidden']
@output_cookies = [
Cookie::new("name" => session_key,
"value" => session_id,
"expires" => option['session_expires'],
"domain" => option['session_domain'],
"secure" => option['session_secure'],
"path" => if option['session_path'] then
option['session_path']
elsif ENV["SCRIPT_NAME"] then
File::dirname(ENV["SCRIPT_NAME"])
else
""
end)
] unless option['no_cookies']
end
# ここでの request はたいてい CGI インスタンス
CGI::Cookie って何?
action_controller/cgi_ext/cookie_performance_fix.rb:
# Rails では cgi.rb のではなくこっちを使う
CGI.module_eval { remove_const "Cookie" }
class CGI
class Cookie < DelegateClass(Array)
attr_accessor("name", "value", "path", "domain", "expires")
attr_reader("secure")
結局、session を作ってしまってから expires を書き換えるには CGI::Cookie#expires= を使えばよく、 CGI::Session から session 用の CGI::Cookie を見るには @output_cookies.first を使えばよい。
lib/raw_session_cookie.rb:
class CGI
def session_cookie
@output_cookies && @output_cookies.first
end
end
module ActionController
class CgiRequest
def session_cookie
@cgi.session_cookie
end
end
end
require 'raw_session_cookie'
class XController
def authenticate
auto = params[:auto]
# これは有効
request.session_cookie.expires = auto ? Time.now + 1.month : nil
しかし、毎回 Set-Cookie ヘッダは出力されるので、filter を使わないとだめだろう (いまここ)。
(追記): RailsChat には書いたけど filter 版。
# migration add_column :members, :auto, :boolean # controller def set_session_expires return unless @member request.session_cookie.expires = @member.auto ? Time.now + 1.month : nil end private :set_session_expires after_filter :set_session_expires
2007-01-26 [長年日記]
2007-01-29 [長年日記]
_ [Capistrano] rollback_migrate タスクを実装するスレ
capistrano の standard recipe は migration の扱いがいまいち。
基本的に migrate タスクは deploy, update 系列と独立している。 deploy_with_migrations だけ連動しているけど、これは rollback できない。デプロイツールとしては片手落ちだ。
やるなら deploy 時点の schema version をどこかに保存しておく必要がある。