積読になっていた「リバースエンジニアリング」を読み始めました。
主にデバック手法について書かれた本で、サンプルプログラムの記述言語はPythonですがOSのコアライブラリにアクセスするためC言語の知識も必要なようです。
なので、馴染み薄なキーワードをメモしていきます。
1章 開発環境のセットアップ
P.11
構造体・・・変数をグループ化したもの。
C
struct beer_recipe
{
int amt_barley;
int amt_water;
}
Python
class beer_recipe(Structure):
_fields_ = [
("amt_barley",c_int),
("amt_water",c_int),
]
共用体・・・すべてのメンバ変数が同一のメモリ位置を占める。
C
union {
long barley_long;
int barley_int;
char barley_char[8];
}barley_amount;
Python
class barley_amount(Union):
_fields_ = [
("barley_long",c_long),
("barley_int",c_int),
("barley_char",c_char * 8),
]
※たまに聞くけどJavaスタートの僕には馴染みが薄い。
P.13
Python ctypesで配列を定義・・・その配列に割り当てたい要素の数だけ型を乗算する。
2章 デバッガの基本原理
P.15
ホワイトボックスデバッガ・・・ソースコードを細やかにトレースする機能を備えたもの。
ブラックボックスデバッガ
ユーザーモード(ring 3)・・・アプリケーションが動作するプロセッサモード(CPUが動作権限を制限するモード)。ユーザモードの場合、アプリケーションは最小の権限で動作する。
カーネルモード(ring 0)・・・権限が最高レベルとなる。OSの中核部分とドライバその他低水準のコンポーネントが作動する。
P.16
OllyDbg・・・ユーザーモードデバッガの代表格。
知的デバッガ・・・スクリプトの利用やコールフックをはじめ広範な機能をサポート。特にバグの検出やリバースエンジニアリングに役立つ高度な機能を備えているのが一般的。
PyDbg・・・知的デバッガの代表格。
Immunity Debugger・・・知的デバッガの代表格。
P.17-18
汎用レジスタ・・・以下8つのレジスタ。
EAX・・・アキュムレータ。計算処理の遂行と関数からの戻り値格納。
EDX・・・データレジスタ。EAXの拡張。
ECX・・・カウントレジスタ。ループ処理用。当レジスタは、上方向ではなく下方向にカウントすることが重要。(ループカウンタがカウントアップの場合、実際のコードとアセンブリコードが逆になる。)
ESI・・・データ処理のソースインデックス。入力データストリームの位置を保持。読み取り用。
EDI・・・デスティネーションインデックス。データ処理の結果を格納する位置を指すポインタ。書き込み用。
ESP・・・スタックポインタ。スタックの先頭を指すため、戻りアドレスを指すことになる。
EBP・・・ベースポインタ。呼び出しスタックの最下部を指す。
EBX・・・特定の用途向けに設計されていない唯一のレジスタ。必要に応じてデータ記憶に使用することも可能。
EIP・・・各時点で実行される命令を指す。上記の汎用レジスタには含まれないが重要なレジスタ。
P.18-20
スタック・・・ローカル変数がスタック上にアロケートされる仕組みが重要。
P.20-21
デバッガ・・・デバッグイベントを待つ永久ループとして作動。
デバックイベント・・・(一般的なもの)ブレークポイント到達。メモリ違反(アクセス違反、セグメンテーションフォールととも言う)。デバッグ対象プログラムが生成した例外。
P.20-28
ブレークポイント
ソフトウェアブレークポイント
ハードウェアブレークポイント
メモリブレークポイント
3章 Windowsデバッガの構築
P.32
windll.kernel32.CreateProcessA()・・・Windowsプロセスの生成。
P.36-37
windll.kernel32.OpenProcess()・・・プロセスのハンドル取得。
windll.kernel32.DebugActiveProcess()・・・プロセスにアタッチ。
windll.kernel32.WaitForDebugEvent()・・・デバッグイベントの捕捉。
windll.kernel32.ContinueDebugEvent()・・・デバッグイベント捕捉後、プロセス再開。
windll.kernel32.DebugActiveProcessStop()・・・デバッガからプロセス切り離し。
P.42-43
windll.kernel32.OpenThread()・・・スレッドのハンドル取得。
windll.kernel32.CreateToolhelp32Snapshot()・・・スレッドを列挙。
windll.kernel32.Thread32First()・・・列挙したスレッドの先頭を取得。
windll.kernel32.Thread32Next()・・・次のスレッドを取得。
windll.kernel32.GetThreadContext()・・・スレッドのコンテキスト情報を取得。
windll.kernel32.SetThreadContext()・・・スレッドのコンテキスト情報を変更。
windll.kernel32.CloseHandle()・・・スレッドのハンドルを解放。
P.46
デバックイベント一覧
イベントコード/イベントコード値/共用体uの値
0x1/EXCEPTION_DBUG_EVENT/u.Exception
0x2/CREATE_THREAD_DEBUG_EVENT/u.CreateThread
0x3/CREATE_PROCESS_DEBUG_EVENT/u.CreateProcessInfo
0x4/EXIT_THREAD_DEBUG_EVENT/u.ExitThread
0x5/EXIT_PROCESS_DEGUG_EVENT/u.ExitProcess
0x6/LOAD_DLL_DEBUG_EVENT/u.LoadDll
0x7/UNLOAD_DLL_DEBUG_EVENT/u.UnloadDll
0x8/OUTPUT_DEBUG_STRING_EVENT/u.DebugString
0x9/RIP_EVENT/u.RipInfo
P48-49
例外イベントコード一覧
例外イベントコード/例外イベントコード値/説明
0xC0000005/EXCEPTION_ACCESS_VIOLATION/アクセス違反
0x80000003/EXCEPTION_BREAKPOINT/ソフトウェアブレークポイント
0x80000001/EXCEPTION_GUARD_PAGE/メモリブレークポイント
0x80000004/EXCEPTION_SINGLE_STEP/ハードウェアブレークポイント
P.50-51
windll.kernel32.ReadProcessMemory・・・プロセスのメモリ読み込み。
windll.kernel32.WriteProcessMemory・・・プロせずのメモリ書き込み。
P.52-53
windll.kernel32.GetModuleHandleA・・・モジュール(.dll、.exe)へのハンドル取得。
windll.kernel32.GetProcAddress・・・関数の仮想アドレスを検出。
P.61
windll.kernel32.GetSystemInfo・・・デフォルトのページサイズの問い合わせなど。
P.61-63
windll.kernel32.VirtualQueryEx・・・該当するページに関する情報を取得。
windll.kernel32.VirtualProtectEx・・・パーミッションを設定するのに利用。
4章 PyDbg - ピュアPythonのWindowsデバッガ
P.67-69
ブレークポイントハンドラ
P.69-72
アクセス違反ハンドラ
クラッシュハンドラ
P.73-75
プロセススナップショット
青い帽子のBookMark
2012年1月22日日曜日
2011年9月17日土曜日
Head First Rails
図書館で借りてきた本。RailsとRubyは初体験。
現バージョン(3.1.0)と本でコマンドが異なっていて少し困惑。
P.7
アプリケーション新規作成
>rails new アプリケーション名
P.8
アプリケーション起動
>cd アプリケーションのディレクトリ
>rails server
P.9
設定よりも規約・・・CoC(convention over configuration)。規約を一貫させて理解度を上げる。また、自動化もし易い。
Rubyはインタプリタ言語でコンパイル不要。
P.12
CRUD操作に必要なコードとページ作成。scaffold=土台。物理テーブル名はデータ名+s(複数形)になるので注意。
>cd アプリケーションのディレクトリ
>rails generate scaffold データ名 項目名1:string 項目名2:text 項目名3:decimal
P.14
DRY・・・Railsの基本原則。おなじことを繰り返さない。Don't Repeat Yourself.
データベースは、dbフォルダの中。
P.15
テーブル作成などDBの更新。db/migrateにあるmigrationはテーブル作成などのRubyスクリプト。
>cd アプリケーションのディレクトリ
>rake db:migrate
P.22
ビジネスロジック・・・モデルロジックorコントローラロジック
モデルロジック・・・データ管理に関連するルール
コントローラロジック・・・システムのワークフローを管理するルール
P.27
symbol・・・対象に名前を付けるために用いる。常に":"で開始される。メモリの使用効率が良くなる。
P.33
undo機能・・・直前の状態に戻す機能。
P.34
データの構成変更。
>cd アプリケーションのディレクトリ
>rails generate migration Add追加項目名Toデータテーブル名 追加項目:string
>rake db:migrate
P.37
<%=h ...%>・・・ヘルパーメソッドに一つ。特殊文字(<,&など)をエスケープするために使う。
P.50
Modelの作成。
>cd アプリケーションのディレクトリ
>rails generate model データ名 項目名1:string 項目名2:text 項目名3:decimal 項目名4:date 項目名5:integer
>rake db:migrate
P.51
rake db:migrateで作成されるデータファイル。
-->db/development.sqlite3
P.52
Controllerの作成。
>cd アプリケーションのディレクトリ
>rails generate controller データ名+"s"
P.53
SQLite3への接続。
>cd アプリケーションのディレクトリ
>rails dbconsole
P.54
ERB・・・Embedded Ruby。埋め込みRudy。テンプレートからWebページを生成する標準Rubyライブラリ。
P.57
config/routes.rb・・・RailsにWebページの場所を伝える。
※記述サンプルは、config/routes.rbを参照。
P.60
ビジネスオブジェクト、ドメインオブジェクト・・・モデルオブジェクトの別名。
P.67
モデルにデータ取得依頼。(コントローラが使用)
モデル.find(params[:id]) ※ユニークIDで検索
モデル.all ※すべてのデータを検索
P86
配列の繰り返し処理。
配列.each do |配列内のオブジェクト|
# 処理
end
P94
レイアウト・・・あるモデルに属するすべてのテンプレートに対するHTMLのラッパーを定義するもの。
P112
入力画面の作成例 (モデルフォーム)
※form_forの前に"="が必要
<h1>New ad</h1>
<%= form_for(@ad,:url=>{:action=>'create'}) do |f| %>
<p><b>Name</b><br /><%= f.text_field :name %></p>
<p><b>Description</b><br /><%= f.text_area :description %></p>
<p><b>Price</b><br /><%= f.text_field :price %></p>
<p><b>Seller</b><br /><%= f.text_field :seller_id %></p>
<p><b>Email</b><br /><%= f.text_field :email %></p>
<p><b>Img url</b><br /><%= f.text_field :img_url %></p>
<p><%= f.submit "Create" %></p>
<% end %>
P117
モデルの新オブジェクト作成。(コントローラが使用)
モデル.new
P120
モデルの新オブジェクトをハッシュテーブルのパラメータを初期値にして作成。フォームからサブミットされた値を設定するのに使用する。
モデル.new(ハッシュテーブル(ex.params[:ad]))
P122
モデルをDBに登録
モデルのインスタンス.save
P132
別のページにリダイレクト。(コントローラが使用)
ex.
redirect_to "/ads/#{@ad.id}"
P139
モデルの更新。(コントローラが使用)
モデルのインスタンス.update_attributes(ハッシュテーブル)
ex.
def update
@ad = Ad.find(params[:id])
@ad.update_attributes(params[:ad])
redirect_to "/ads/#{@ad.id}"
end
P147
モデルの削除。(コントローラが使用)
モデルのインスタンス.destroy
P162
検索画面の作成例 (非モデルフォーム)
<%= form_tag "/client_workouts/find" do %>
<% text_field_tag :search_string %>
<% submit_tag "Search" %>
<% end %>
P168
Webサーバコンソールに標準出力。
puts "出力文字列"
P170
アプリケーションで使用可能なルートの表示。
>rake routes
P174
モデルにデータ取得依頼その2。(コントローラが使用)
モデル.find_all_by_テーブル項目名(パラメータ) ※検索対象のテーブル項目を指定して検索
P181
モデルにデータ取得依頼その3。(コントローラが使用)
モデル.all(:conditions=>[検索条件,パラメータ,パラメータ,・・・(複数パラメータを渡すことが可能)]※細かい条件を指定して検索
現バージョン(3.1.0)と本でコマンドが異なっていて少し困惑。
P.7
アプリケーション新規作成
>rails new アプリケーション名
P.8
アプリケーション起動
>cd アプリケーションのディレクトリ
>rails server
P.9
設定よりも規約・・・CoC(convention over configuration)。規約を一貫させて理解度を上げる。また、自動化もし易い。
Rubyはインタプリタ言語でコンパイル不要。
P.12
CRUD操作に必要なコードとページ作成。scaffold=土台。物理テーブル名はデータ名+s(複数形)になるので注意。
>cd アプリケーションのディレクトリ
>rails generate scaffold データ名 項目名1:string 項目名2:text 項目名3:decimal
P.14
DRY・・・Railsの基本原則。おなじことを繰り返さない。Don't Repeat Yourself.
データベースは、dbフォルダの中。
P.15
テーブル作成などDBの更新。db/migrateにあるmigrationはテーブル作成などのRubyスクリプト。
>cd アプリケーションのディレクトリ
>rake db:migrate
P.22
ビジネスロジック・・・モデルロジックorコントローラロジック
モデルロジック・・・データ管理に関連するルール
コントローラロジック・・・システムのワークフローを管理するルール
P.27
symbol・・・対象に名前を付けるために用いる。常に":"で開始される。メモリの使用効率が良くなる。
P.33
undo機能・・・直前の状態に戻す機能。
P.34
データの構成変更。
>cd アプリケーションのディレクトリ
>rails generate migration Add追加項目名To
>rake db:migrate
P.37
<%=h ...%>・・・ヘルパーメソッドに一つ。特殊文字(<,&など)をエスケープするために使う。
P.50
Modelの作成。
>cd アプリケーションのディレクトリ
>rails generate model データ名 項目名1:string 項目名2:text 項目名3:decimal 項目名4:date 項目名5:integer
>rake db:migrate
P.51
rake db:migrateで作成されるデータファイル。
-->db/development.sqlite3
P.52
Controllerの作成。
>cd アプリケーションのディレクトリ
>rails generate controller データ名+"s"
P.53
SQLite3への接続。
>cd アプリケーションのディレクトリ
>rails dbconsole
P.54
ERB・・・Embedded Ruby。埋め込みRudy。テンプレートからWebページを生成する標準Rubyライブラリ。
P.57
config/routes.rb・・・RailsにWebページの場所を伝える。
※記述サンプルは、config/routes.rbを参照。
P.60
ビジネスオブジェクト、ドメインオブジェクト・・・モデルオブジェクトの別名。
P.67
モデルにデータ取得依頼。(コントローラが使用)
モデル.find(params[:id]) ※ユニークIDで検索
モデル.all ※すべてのデータを検索
P86
配列の繰り返し処理。
配列.each do |配列内のオブジェクト|
# 処理
end
P94
レイアウト・・・あるモデルに属するすべてのテンプレートに対するHTMLのラッパーを定義するもの。
P112
入力画面の作成例 (モデルフォーム)
※form_forの前に"="が必要
<h1>New ad</h1>
<%= form_for(@ad,:url=>{:action=>'create'}) do |f| %>
<p><b>Name</b><br /><%= f.text_field :name %></p>
<p><b>Description</b><br /><%= f.text_area :description %></p>
<p><b>Price</b><br /><%= f.text_field :price %></p>
<p><b>Seller</b><br /><%= f.text_field :seller_id %></p>
<p><b>Email</b><br /><%= f.text_field :email %></p>
<p><b>Img url</b><br /><%= f.text_field :img_url %></p>
<p><%= f.submit "Create" %></p>
<% end %>
P117
モデルの新オブジェクト作成。(コントローラが使用)
モデル.new
P120
モデルの新オブジェクトをハッシュテーブルのパラメータを初期値にして作成。フォームからサブミットされた値を設定するのに使用する。
モデル.new(ハッシュテーブル(ex.params[:ad]))
P122
モデルをDBに登録
モデルのインスタンス.save
P132
別のページにリダイレクト。(コントローラが使用)
ex.
redirect_to "/ads/#{@ad.id}"
P139
モデルの更新。(コントローラが使用)
モデルのインスタンス.update_attributes(ハッシュテーブル)
ex.
def update
@ad = Ad.find(params[:id])
@ad.update_attributes(params[:ad])
redirect_to "/ads/#{@ad.id}"
end
P147
モデルの削除。(コントローラが使用)
モデルのインスタンス.destroy
P162
検索画面の作成例 (非モデルフォーム)
<%= form_tag "/client_workouts/find" do %>
<% text_field_tag :search_string %>
<% submit_tag "Search" %>
<% end %>
P168
Webサーバコンソールに標準出力。
puts "出力文字列"
P170
アプリケーションで使用可能なルートの表示。
>rake routes
P174
モデルにデータ取得依頼その2。(コントローラが使用)
モデル.find_all_by_テーブル項目名(パラメータ) ※検索対象のテーブル項目を指定して検索
P181
モデルにデータ取得依頼その3。(コントローラが使用)
モデル.all(:conditions=>[検索条件,パラメータ,パラメータ,・・・(複数パラメータを渡すことが可能)]※細かい条件を指定して検索
ex.
@client_workouts = ClientWorkout.all(:conditions=>["client_name = ? OR trainer = ?", params[:search_string],params[:search_string]])
P194
バリデータ・・・モデルで属性の検証を行う機能。
ex.
class ClientWorkout < ActiveRecord::Base
validates_numericality_of :paid_amount
end
数値フィールドの検証。
validates_numericality_of :検証する属性, "エラーメッセージ(省略可)"
P197
必須フィールドの検証
validates_presence_of :検証する属性, "エラーメッセージ(省略可)"
P199
フィールドの長さ検証
validates_length_of :検証する属性, :maximum=>最大長
フィールドのユニーク検証
validates_uniqueness_of :検証する属性
フィールドのフォーマット検証
validates_format_of :検証する属性, :with=>/検証するフォーマット/
フィールドのスペル検証(属性が指定された値と同じか検証する)
validates_inclusion_of :検証する属性, in=>[検証する値1,検証する値2,・・・,検証する値n]
P210
エラー処理の実装例。
(コントローラに実装)
if @ad.save
redirect_to "/ads/#{@ad.id}"
else
render :template => "ad/new" ←※URLではないので注意
end
(Viewに実装)
<% if @ad.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@ad.errors.count, "error") %> prohibited this client_workout from being saved:</h2>
<ul>
<% @ad.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
P226
各ERBファイルの説明。
レイアウト・・・複数のWebページに一貫した外観を与えるファイル。
テンプレート・・・Webページのメインコンテンツファイル。アクションと関連付けられている。
パーシャル・・・ページの部分的な断片を出力するサブルーチン。
P230
パーシャルの作成。
テンプレートファイルをコピーして、ファイル名の先頭に"_"を付ける。Railsは、先頭にアンダースコアがついているかどうかでパーシャルとテンプレートを区別している。
※バージョン3.1.0の場合、_form.html.erbもコピーする必要があるので注意。
P231
パーシャルをテンプレートに含める。
ex._new_seat.html.erbを含める場合
<%= render :partial=>"new_seat" %>
先頭のアンダースコアと末尾の.html.erbは省略。
※_form.html.erbのソースを_new_seat.html.erbのフォーム部分にコピーしておく必要あり。
P235
パーシャルにローカル変数を渡す。(コントローラの変数を参照しないほうがコントローラとパーシャルの結びつきが強くならないので管理が楽。)
ex._new_seat.html.erbを含める場合
<%= render :partial=>"new_seat", :locals=>{:seat=>Seat.new(:flight_id=>@flight.id)} %>
※_new_seat.html.erbの参照も@seatからローカル変数seatに変更すること。
P247
テーブルの関連をモデルに定義する。
ex.Seatsテーブルのflight_idとFlightsテーブルのidを関連付けする。FlightsテーブルがSeatsテーブルを複数持っている。
class Flight < ActiveRecord::Base
has_many :seats
end
※カラムの名前付けが重要。Flight.idと関連付けするには、Seatsテーブルのカラム名は、flight_idとする必要がある。
関連を使ってデータを取得する。
ex.
<%= render :partial=>"seat_list", :locals=>{:seats=>@flight.seats} %>
P.253
テーブルの関連をモデルに定義する。
ex.SeatsテーブルがFligthsテーブルに属している。
Class Seats < ActiveRecord::Base
belongs_to :flight
end
バリデーションチェックをカスタマイズする。
ex.
Class Seats < ActiveRecord::Base
belogns_to :flight
validate :baggage_allowance_check,:name_check
def baggage_allowance_check
if baggage > flight.baggage_allowance
errors.add(:baggage,"You have too much baggage") ※フォーカスを当てる項目がない場合、:base
end
end
def name_check
if name == flight_id.to_s #to_sで数値を文字列に変換
errors.add(:name,"Your name is the same as your flight number")
end
end
end
P.272
Rails3.1.0でprototype.jsを使用する場合、アプリケーション作成時のコマンドで以下のオプションを使用する。
>rails new アプリケーション名 -j prototype
(参考資料)
http://ja.asciicasts.com/episodes/265-rails-3-1-overview
ex.
<div id="seats">
<%= render :partial=>"seat_list", :locals=>{:seats=>@flight.seats} %>
</div>
<%= link_to "Refresh seats",
:url=>"/flights/#{@flight.id}/seats",
:method=>"get",
:update=>"seats",
:remote=> true
%>
(補足)
後からアプリケーションにprototype.jsを導入する場合、以下のコマンドを実行。
rails plugin install git://github.com/rails/prototype_legacy_helper.git
(参考資料)
https://github.com/rails/prototype_legacy_helper
P282
タイマーイベントを受け取る。
本来は
<div id="seats">
<%= render :partial=>"seat_list", :locals=>{:seats=>@flight.seats} %>
</div>
<%= periodically_call_remote :url=>"/flights/#{@flight.id}/seats",
:method=>"get",
:update=>"seats",
:frequency=> 20
%>
と本の通り書きたかったが、Railsのバージョンにより、仕方なく
<%= javascript_tag do %>
$(document).ready(
function(){
setInterval(function(){
$.ajax({
url: "<%= "/flights/#{@flight.id}/seats" %>",
type: "get",
dataType: "html",
success: function(html) {
if (document.getElementById("seats") != null)
{
$("#list").remove();
}
$("<div>", { id:"list"}).appendTo("#seats");
$("#list").append(html);
}
});
}, 20000 );
});
<% end %>
<div id="seats">
<div id="list">
<%= render :partial=>"seat_list", :locals=>{:seats=>@flight.seats} %>
</div>
</div>
<%= link_to "Refresh seats",
:url=>"/flights/#{@flight.id}/seats",
:method=>"get",
:update=>"list"
%>
と記述。(他によい方法があるのかは不明)
P287-290
AjaxリクエストでフォームをPOST送信する。
(テンプレートを以下のように修正)
<%= form_for(seat) do |f| %>
⇒<%= form_for(seat, :update=>'seats', :remote=>true) do |f| %>
(コントローラを修正)
def create
@seat = Seat.new(params[:seat])
@seat.save
render :partial=>"flights/seat_list", :locals=>{:seats=>@seat.flight.seats}
end
P296-304
Ajaxでページの複数個所を更新する。
⇒コントローラでHTMLの代わりにJavaScriptを返却する。
※ただし、JavaScriptにprototype.jsを選択していない(jQueryを選択した)場合以下の方法は使用できない。
(コントローラを修正)
def create
@seat = Seat.new(params[:seat])
render :update do |page|
if @seat.save
page.replace_html 'notice', 'Seat was successfully booked'
else
page.replace_html 'notice', 'Sorry - the seat could not be booked'
end
end
end
(レイアウトに追加)
<p style="color: green" id="notice">
<%= flash[:notice] %>
</p>
(テンプレートを修正)
<%= form_for(seat, :update=>'seats', :remote=>true) do |f| %>
⇒<%= form_for(seat, :remote=>true) do |f| %>
P321
モデルオブジェクトからXMLを生成。
def show_with_map
@incident = Incident.find(params[:id])
render :text=>@incident.to_xml
end
※renderメソッドは、ブラウザに返すレスポンスを生成。
P324
モデルオブジェクトから生成したXMLのレイアウトを修正する。
def show_with_map
@incident = Incident.find(params[:id])
render :text=>@incident.to_xml(
:only=>[:latitude, :longitude, :title, :description],
:root=>"data")
end
P330
どのフォーマット(例の場合、xml or html)でレスポンスを返すかを判断する処理を実装。
(ルートの実装)
match 'incidents/map/:id.:format' => 'incidents#show_with_map'
(コントローラの実装)
def show_with_map
@incident = Incident.find(params[:id])
respond_to do |format|
format.html
format.xml {
render :text=>@incident.to_xml(
:only=>[:latitude, :longitude, :title, :description],
:root=>"data")
}
end
end
※to_xmlは、配列にも使用可能。P340
(テンプレートの実装)
<%=render(:partial=>'map',:locals=>{:data=>"#{@incident.id}.xml"}) %>
P335
コントローラにJavaScriptのAjaxリクエストとブラウザからのリクエストを区別させる方法。
式request.xhr?がtrueならAjaxリクエスト。(ただし、Prototypeライブラリのみ)
デフォルトのテンプレート(アクション名とマッチしているもの)で処理できる場合は、renderメソッドの呼び出しは省略可。
P346
更新日付が24時間以内のデータ取得サンプル。
def news
@incidents = Incident.all(:conditions=>['updated_at > ?',Time.now.yesterday])
render :xml=>@incidents
end
P352
XMLビルダーテンプレート。RSSフィードに使用。
(XMLビルダーテンプレートの実装)
xml.rss(:version=>"2.0"){
xml.channel{
xml.title("Head First Climbers News")
xml.link("http://localhost:3000/incidents/")
@incidents.each do |incident|
xml.item{
xml.title(incident.title)
xml.description(incident.description)
xml.link("http://localhost:3000/incidents/#{incident.id}")
}
end
}
}
※ファイル名=news.xml.builderで保存
P353
ページにRSSフィードを追加。
⇒ブラウザは、<link../>タグの参照先を探して、ニュースフィードを認識する。
(レイアウトのヘッダー部に追加)※application.html.erb
<%= auto_discovery_link_tag(:rss, {:action=>'news'}) %>
P385
メソッド名の末尾に?を付ける理由のは、Rubyの慣習。trueかfalseを返却するメソッドに付ける。
ex. new_record?
P388
RESTfulルートについて。
ルートに"resources :incidents"と記述すると自動で標準的なルートが生成される。
これは、以下のコマンドで確認可能。
>rake routes
上記画像のedit_incidentにアクセスするには、
edit_incident_path(@incident) ※相対パスを返却(ex. /incidents/3/edit)
または、
edit_incident_url(@incident) ※絶対パスを返却(ex. http://localhost:3000/incidents/3/edit)
@client_workouts = ClientWorkout.all(:conditions=>["client_name = ? OR trainer = ?", params[:search_string],params[:search_string]])
P194
バリデータ・・・モデルで属性の検証を行う機能。
ex.
class ClientWorkout < ActiveRecord::Base
validates_numericality_of :paid_amount
end
数値フィールドの検証。
validates_numericality_of :検証する属性, "エラーメッセージ(省略可)"
P197
必須フィールドの検証
validates_presence_of :検証する属性, "エラーメッセージ(省略可)"
P199
フィールドの長さ検証
validates_length_of :検証する属性, :maximum=>最大長
フィールドのユニーク検証
validates_uniqueness_of :検証する属性
フィールドのフォーマット検証
validates_format_of :検証する属性, :with=>/検証するフォーマット/
フィールドのスペル検証(属性が指定された値と同じか検証する)
validates_inclusion_of :検証する属性, in=>[検証する値1,検証する値2,・・・,検証する値n]
P210
エラー処理の実装例。
(コントローラに実装)
if @ad.save
redirect_to "/ads/#{@ad.id}"
else
render :template => "ad/new" ←※URLではないので注意
end
(Viewに実装)
<% if @ad.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@ad.errors.count, "error") %> prohibited this client_workout from being saved:</h2>
<ul>
<% @ad.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
P226
各ERBファイルの説明。
レイアウト・・・複数のWebページに一貫した外観を与えるファイル。
テンプレート・・・Webページのメインコンテンツファイル。アクションと関連付けられている。
パーシャル・・・ページの部分的な断片を出力するサブルーチン。
P230
パーシャルの作成。
テンプレートファイルをコピーして、ファイル名の先頭に"_"を付ける。Railsは、先頭にアンダースコアがついているかどうかでパーシャルとテンプレートを区別している。
※バージョン3.1.0の場合、_form.html.erbもコピーする必要があるので注意。
P231
パーシャルをテンプレートに含める。
ex._new_seat.html.erbを含める場合
<%= render :partial=>"new_seat" %>
先頭のアンダースコアと末尾の.html.erbは省略。
※_form.html.erbのソースを_new_seat.html.erbのフォーム部分にコピーしておく必要あり。
P235
パーシャルにローカル変数を渡す。(コントローラの変数を参照しないほうがコントローラとパーシャルの結びつきが強くならないので管理が楽。)
ex._new_seat.html.erbを含める場合
<%= render :partial=>"new_seat", :locals=>{:seat=>Seat.new(:flight_id=>@flight.id)} %>
※_new_seat.html.erbの参照も@seatからローカル変数seatに変更すること。
P247
テーブルの関連をモデルに定義する。
ex.Seatsテーブルのflight_idとFlightsテーブルのidを関連付けする。FlightsテーブルがSeatsテーブルを複数持っている。
class Flight < ActiveRecord::Base
has_many :seats
end
※カラムの名前付けが重要。Flight.idと関連付けするには、Seatsテーブルのカラム名は、flight_idとする必要がある。
関連を使ってデータを取得する。
ex.
<%= render :partial=>"seat_list", :locals=>{:seats=>@flight.seats} %>
P.253
テーブルの関連をモデルに定義する。
ex.SeatsテーブルがFligthsテーブルに属している。
Class Seats < ActiveRecord::Base
belongs_to :flight
end
バリデーションチェックをカスタマイズする。
ex.
Class Seats < ActiveRecord::Base
belogns_to :flight
validate :baggage_allowance_check,:name_check
def baggage_allowance_check
if baggage > flight.baggage_allowance
errors.add(:baggage,"You have too much baggage") ※フォーカスを当てる項目がない場合、:base
end
end
def name_check
if name == flight_id.to_s #to_sで数値を文字列に変換
errors.add(:name,"Your name is the same as your flight number")
end
end
end
P.272
Rails3.1.0でprototype.jsを使用する場合、アプリケーション作成時のコマンドで以下のオプションを使用する。
>rails new アプリケーション名 -j prototype
(参考資料)
http://ja.asciicasts.com/episodes/265-rails-3-1-overview
ex.
<div id="seats">
<%= render :partial=>"seat_list", :locals=>{:seats=>@flight.seats} %>
</div>
<%= link_to "Refresh seats",
:url=>"/flights/#{@flight.id}/seats",
:method=>"get",
:update=>"seats",
:remote=> true
%>
(補足)
後からアプリケーションにprototype.jsを導入する場合、以下のコマンドを実行。
rails plugin install git://github.com/rails/prototype_legacy_helper.git
(参考資料)
https://github.com/rails/prototype_legacy_helper
P282
タイマーイベントを受け取る。
本来は
<div id="seats">
<%= render :partial=>"seat_list", :locals=>{:seats=>@flight.seats} %>
</div>
<%= periodically_call_remote :url=>"/flights/#{@flight.id}/seats",
:method=>"get",
:update=>"seats",
:frequency=> 20
%>
と本の通り書きたかったが、Railsのバージョンにより、仕方なく
<%= javascript_tag do %>
$(document).ready(
function(){
setInterval(function(){
$.ajax({
url: "<%= "/flights/#{@flight.id}/seats" %>",
type: "get",
dataType: "html",
success: function(html) {
if (document.getElementById("seats") != null)
{
$("#list").remove();
}
$("<div>", { id:"list"}).appendTo("#seats");
$("#list").append(html);
}
});
}, 20000 );
});
<% end %>
<div id="seats">
<div id="list">
<%= render :partial=>"seat_list", :locals=>{:seats=>@flight.seats} %>
</div>
</div>
<%= link_to "Refresh seats",
:url=>"/flights/#{@flight.id}/seats",
:method=>"get",
:update=>"list"
%>
と記述。(他によい方法があるのかは不明)
P287-290
AjaxリクエストでフォームをPOST送信する。
(テンプレートを以下のように修正)
<%= form_for(seat) do |f| %>
⇒<%= form_for(seat, :update=>'seats', :remote=>true) do |f| %>
(コントローラを修正)
def create
@seat = Seat.new(params[:seat])
@seat.save
render :partial=>"flights/seat_list", :locals=>{:seats=>@seat.flight.seats}
end
P296-304
Ajaxでページの複数個所を更新する。
⇒コントローラでHTMLの代わりにJavaScriptを返却する。
※ただし、JavaScriptにprototype.jsを選択していない(jQueryを選択した)場合以下の方法は使用できない。
(コントローラを修正)
def create
@seat = Seat.new(params[:seat])
render :update do |page|
if @seat.save
page.replace_html 'notice', 'Seat was successfully booked'
else
page.replace_html 'notice', 'Sorry - the seat could not be booked'
end
end
end
(レイアウトに追加)
<p style="color: green" id="notice">
<%= flash[:notice] %>
</p>
(テンプレートを修正)
<%= form_for(seat, :update=>'seats', :remote=>true) do |f| %>
⇒<%= form_for(seat, :remote=>true) do |f| %>
P321
モデルオブジェクトからXMLを生成。
def show_with_map
@incident = Incident.find(params[:id])
render :text=>@incident.to_xml
end
※renderメソッドは、ブラウザに返すレスポンスを生成。
P324
モデルオブジェクトから生成したXMLのレイアウトを修正する。
def show_with_map
@incident = Incident.find(params[:id])
render :text=>@incident.to_xml(
:only=>[:latitude, :longitude, :title, :description],
:root=>"data")
end
P330
どのフォーマット(例の場合、xml or html)でレスポンスを返すかを判断する処理を実装。
(ルートの実装)
match 'incidents/map/:id.:format' => 'incidents#show_with_map'
(コントローラの実装)
def show_with_map
@incident = Incident.find(params[:id])
respond_to do |format|
format.html
format.xml {
render :text=>@incident.to_xml(
:only=>[:latitude, :longitude, :title, :description],
:root=>"data")
}
end
end
※to_xmlは、配列にも使用可能。P340
(テンプレートの実装)
<%=render(:partial=>'map',:locals=>{:data=>"#{@incident.id}.xml"}) %>
P335
コントローラにJavaScriptのAjaxリクエストとブラウザからのリクエストを区別させる方法。
式request.xhr?がtrueならAjaxリクエスト。(ただし、Prototypeライブラリのみ)
デフォルトのテンプレート(アクション名とマッチしているもの)で処理できる場合は、renderメソッドの呼び出しは省略可。
P346
更新日付が24時間以内のデータ取得サンプル。
def news
@incidents = Incident.all(:conditions=>['updated_at > ?',Time.now.yesterday])
render :xml=>@incidents
end
P352
XMLビルダーテンプレート。RSSフィードに使用。
(XMLビルダーテンプレートの実装)
xml.rss(:version=>"2.0"){
xml.channel{
xml.title("Head First Climbers News")
xml.link("http://localhost:3000/incidents/")
@incidents.each do |incident|
xml.item{
xml.title(incident.title)
xml.description(incident.description)
xml.link("http://localhost:3000/incidents/#{incident.id}")
}
end
}
}
※ファイル名=news.xml.builderで保存
P353
ページにRSSフィードを追加。
⇒ブラウザは、<link../>タグの参照先を探して、ニュースフィードを認識する。
(レイアウトのヘッダー部に追加)※application.html.erb
<%= auto_discovery_link_tag(:rss, {:action=>'news'}) %>
P385
メソッド名の末尾に?を付ける理由のは、Rubyの慣習。trueかfalseを返却するメソッドに付ける。
ex. new_record?
P388
RESTfulルートについて。
ルートに"resources :incidents"と記述すると自動で標準的なルートが生成される。
これは、以下のコマンドで確認可能。
>rake routes
上記画像のedit_incidentにアクセスするには、
edit_incident_path(@incident) ※相対パスを返却(ex. /incidents/3/edit)
または、
edit_incident_url(@incident) ※絶対パスを返却(ex. http://localhost:3000/incidents/3/edit)
2011年2月13日日曜日
入門 自然言語処理
[キーワード]
P.22
コロケーション・・・非常に頻繁に共起する一連の単語列。類似した意味を持つ単語での置き換えがしづらいという特徴を持つ。
バイグラム・・・単語のペア。コロケーションとは、本質的には頻繁に出現するバイグラム。
P.30
語義曖昧性解消・・・指定された文脈において、単語がどのような語義として使われているかを推定すること。
P.31
代名詞解析
照応解析・・・代名詞や名詞句が何を示しているかを特定すること。
意味役割付与・・・名詞句がどのように動詞と関係しているか、動作主 or 対象 or 手段 etcを特定すること。
P.33
テキストアラインメント・・・同じ内容が2つ以上の言語で書かれた文書を大量に集めることで、そこから自動的に文書のペアを作ること。
チューリングテスト・・・ユーザーのテキスト入力に対して、人工知能による応答が人が答えているのと区別できないくらい自然であるかをチェックするもの。
P.34
含意関係認識・・・RTE(Recognizing Textual Entailment)。文章から内包された意味を認識させること。
P.35
会話システムの処理フロー・・・音声認識 -> 形態素・語彙解析 -> 構文解析 -> 文脈推定 -> 応用推論・実行 (折り返し) -> 発話計画 -> 構文生成 -> 形態素生成 -> 音声合成
P.41
テキストコーパス・・・巨大なテキスト。多くのコーパスは、1つ以上のジャンルから集められた素材をバランスよく含むようにデザインされている。
P.113
ステミング・・・単語から接辞を取り除く処理。
見出し語化・・・語形を辞書に記述されているものに変換する作業。
ステマー・・・ステミングを行うプログラム。
レマタイザ・・・見出し語化するプログラム。
P.115
非標準語の識別
トークン化・・・識別可能な言語学上の単位に変換する作業
トークナイザ・・・トークン化するプログラム。
P.148
ジェネレータ式
P.150
手続き的スタイル
宣言的スタイル
P.160
dctestブロック
「epytext」マークアップ言語
P.161
ラムダ式・・・名前なし関数
P.162
ジェネレータ yield文まで進んで処理を停止(P.163の例文難しい)
P.163
Haskel・・・関数型プログラム言語
高階関数・・・関数を引数にした関数
P.164
名前付き引数
キーワード引数
*args・・・任意の名前のない引数
**kwargs・・・任意のキーワード引数
P.165
*変数名
P.166
__file__変数
P.175
文字トライ
P.177
セットの要素は自動的にインデックスが構築される→リストより要素の存在チェック早い
動的計画法(Dynamic Programming)・・・一度説いた問題をルックアップテーブルに保持
P.184
線形代数
特異値分解
潜在意味解析
P.193
品詞タグ付け、POSタグ付け
品詞・・・名詞や動詞など機能や形態などによって分類したもの。単語クラス、語彙範疇と呼ばれることもある。
P.194
nltk.help.upenn_tagset('品詞タグ')・・・タグの説明
P.201
形容詞
副詞
冠詞(限定詞)
法助動詞
人称代名詞
P.204
ディクショナリ型(連想配列、ハッシュ配列、マップ)
P.208
イミュータブル・・・値が不変なオブジェクト⇔ミュータブル
defaultdict
P.212
nltk.Index・・・defaultdict(list) + 初期化処理
nlltk.FreqDist・・・defaultdict(int) + 初期化処理
P.214
デフォルトタガー
P.215
正規表現タガー
P.216
ルックアップタガー・・・nltk.UnigramTagger
バックオフ
P.217
ゴールドスタンダード
P.219
ユニグラムタガー・・・≒ルックアップタガー
ユニグラムタガーの訓練・・・初期化にタグ付けした文章データを渡す
P.220
Nグラムタガー・・・1グラムタガー(ユニグラムタガー)、バイグラムタガー、トライグラムタガー。これは、文の境界をまたぐ文脈を考慮すべきではない。そのため、NLTKでは文のリストに対して処理している。教師あり学習。
P.221
疎(スパース)データ問題
適合率と再現率のトレードオフ・・・精度とカバー率の間のトレードオフ。対処法としては、精度の高いアルゴリズムを使用できるときは使い、必要に応じて適用範囲の広いアルゴリズムをフォールバックする。
P.224
混同行列・・・タグの付け間違い調べる方法のひとつ
P.225
ブリルタグ付け・・・Brill tagging、帰納的タグ付け法、変換を利用した学習、教師あり学習。
P.239
教師あり分類
P.240
素性集合・・・それぞれの入力の基礎的な情報
P.241
分類器作成第一ステップ・・・素性の決定、素性の符号化
nltk.NativeBayesClassifier.train
nltk.NativeBayesClassifier.classify
P.242
nltk.classify.accuracy
nltk.NativeBayesClassifier.show_most_informative_features
尤度比(ゆうどひ)・・・ある素性が異なる素性の何倍多かったか。
P.243
キッチンシンクアプローチ・・・考えられる素性をすべて利用してみてどの素性が実際に役に立つか調べてみる手法。
P.243
エラー分析・・・素性集合を洗練するための生産的な手法。分析用コーパスを開発セット(訓練セット+検証セット)とテストセットに分割する。
訓練セット・・・モデルの訓練に利用。
検証セット・・・エラー分析に利用。
テストセット・・・開発完了後の最終テストに利用。
7章 テキストからの情報抽出
P.281,300
固有表現認識(NER)・・・各文の潜在的に注目すべき実体への言及を探すこと。
関係認識・・・テキスト中の異なる実体同士の関係性を探すこと。
P.282
チャンキング・・・固有表現認識に利用される基礎技術。複数のトークンで構成されたテキスト断片に分割し、ラベル付けすること。
P.300
ダックタイピング
固有表現(NE)・・・組織、人物、日付といった特定の種類の何かを指す定名詞句。
P.22
コロケーション・・・非常に頻繁に共起する一連の単語列。類似した意味を持つ単語での置き換えがしづらいという特徴を持つ。
バイグラム・・・単語のペア。コロケーションとは、本質的には頻繁に出現するバイグラム。
P.30
語義曖昧性解消・・・指定された文脈において、単語がどのような語義として使われているかを推定すること。
P.31
代名詞解析
照応解析・・・代名詞や名詞句が何を示しているかを特定すること。
意味役割付与・・・名詞句がどのように動詞と関係しているか、動作主 or 対象 or 手段 etcを特定すること。
P.33
テキストアラインメント・・・同じ内容が2つ以上の言語で書かれた文書を大量に集めることで、そこから自動的に文書のペアを作ること。
チューリングテスト・・・ユーザーのテキスト入力に対して、人工知能による応答が人が答えているのと区別できないくらい自然であるかをチェックするもの。
P.34
含意関係認識・・・RTE(Recognizing Textual Entailment)。文章から内包された意味を認識させること。
P.35
会話システムの処理フロー・・・音声認識 -> 形態素・語彙解析 -> 構文解析 -> 文脈推定 -> 応用推論・実行 (折り返し) -> 発話計画 -> 構文生成 -> 形態素生成 -> 音声合成
P.41
テキストコーパス・・・巨大なテキスト。多くのコーパスは、1つ以上のジャンルから集められた素材をバランスよく含むようにデザインされている。
P.113
ステミング・・・単語から接辞を取り除く処理。
見出し語化・・・語形を辞書に記述されているものに変換する作業。
ステマー・・・ステミングを行うプログラム。
レマタイザ・・・見出し語化するプログラム。
P.115
非標準語の識別
トークン化・・・識別可能な言語学上の単位に変換する作業
トークナイザ・・・トークン化するプログラム。
P.148
ジェネレータ式
P.150
手続き的スタイル
宣言的スタイル
P.160
dctestブロック
「epytext」マークアップ言語
P.161
ラムダ式・・・名前なし関数
P.162
ジェネレータ yield文まで進んで処理を停止(P.163の例文難しい)
P.163
Haskel・・・関数型プログラム言語
高階関数・・・関数を引数にした関数
P.164
名前付き引数
キーワード引数
*args・・・任意の名前のない引数
**kwargs・・・任意のキーワード引数
P.165
*変数名
P.166
__file__変数
P.175
文字トライ
P.177
セットの要素は自動的にインデックスが構築される→リストより要素の存在チェック早い
動的計画法(Dynamic Programming)・・・一度説いた問題をルックアップテーブルに保持
P.184
線形代数
特異値分解
潜在意味解析
P.193
品詞タグ付け、POSタグ付け
品詞・・・名詞や動詞など機能や形態などによって分類したもの。単語クラス、語彙範疇と呼ばれることもある。
P.194
nltk.help.upenn_tagset('品詞タグ')・・・タグの説明
P.201
形容詞
副詞
冠詞(限定詞)
法助動詞
人称代名詞
P.204
ディクショナリ型(連想配列、ハッシュ配列、マップ)
P.208
イミュータブル・・・値が不変なオブジェクト⇔ミュータブル
defaultdict
P.212
nltk.Index・・・defaultdict(list) + 初期化処理
nlltk.FreqDist・・・defaultdict(int) + 初期化処理
P.214
デフォルトタガー
P.215
正規表現タガー
P.216
ルックアップタガー・・・nltk.UnigramTagger
バックオフ
P.217
ゴールドスタンダード
P.219
ユニグラムタガー・・・≒ルックアップタガー
ユニグラムタガーの訓練・・・初期化にタグ付けした文章データを渡す
P.220
Nグラムタガー・・・1グラムタガー(ユニグラムタガー)、バイグラムタガー、トライグラムタガー。これは、文の境界をまたぐ文脈を考慮すべきではない。そのため、NLTKでは文のリストに対して処理している。教師あり学習。
P.221
疎(スパース)データ問題
適合率と再現率のトレードオフ・・・精度とカバー率の間のトレードオフ。対処法としては、精度の高いアルゴリズムを使用できるときは使い、必要に応じて適用範囲の広いアルゴリズムをフォールバックする。
P.224
混同行列・・・タグの付け間違い調べる方法のひとつ
P.225
ブリルタグ付け・・・Brill tagging、帰納的タグ付け法、変換を利用した学習、教師あり学習。
P.239
教師あり分類
P.240
素性集合・・・それぞれの入力の基礎的な情報
P.241
分類器作成第一ステップ・・・素性の決定、素性の符号化
nltk.NativeBayesClassifier.train
nltk.NativeBayesClassifier.classify
P.242
nltk.classify.accuracy
nltk.NativeBayesClassifier.show_most_informative_features
尤度比(ゆうどひ)・・・ある素性が異なる素性の何倍多かったか。
P.243
キッチンシンクアプローチ・・・考えられる素性をすべて利用してみてどの素性が実際に役に立つか調べてみる手法。
P.243
エラー分析・・・素性集合を洗練するための生産的な手法。分析用コーパスを開発セット(訓練セット+検証セット)とテストセットに分割する。
訓練セット・・・モデルの訓練に利用。
検証セット・・・エラー分析に利用。
テストセット・・・開発完了後の最終テストに利用。
7章 テキストからの情報抽出
P.281,300
固有表現認識(NER)・・・各文の潜在的に注目すべき実体への言及を探すこと。
関係認識・・・テキスト中の異なる実体同士の関係性を探すこと。
P.282
チャンキング・・・固有表現認識に利用される基礎技術。複数のトークンで構成されたテキスト断片に分割し、ラベル付けすること。
P.300
ダックタイピング
固有表現(NE)・・・組織、人物、日付といった特定の種類の何かを指す定名詞句。
2010年2月18日木曜日
2010年1月24日日曜日
思わずこんな本買っちゃいました。
2010年1月16日土曜日
過去読んだ本をもう一度 パート1
登録:
投稿 (Atom)




