C++ でごく簡単なShared Object形式のライブラリを書く

プログラムを解読していると、トレース用のファイルへ吐き出す関数が欲しくなるということで、作成。

/usr/include/mylib.h

#include <iostream>
#include <fstream>
#include <string>

void mylog(const std::string& msg);

./mylib.c

#include <mylib.h>

void mylog(const std::string& msg) {
   std::ofstream out_file("/tmp/mylog.log",std::iso::out|std::ios::app);
   if (out_file.fail())
      return;
   out_file << msg << std::endl;
}

#g++ -fPIC -shared mylib.c -o /usr/lib/libmylib.so

-fPIC Position Independent Code 関数はアドレスう空間のどこでも実行可能という意味。Shared Objectは動的にメモリ空間へロードされるので、どんなアドレスでも実行できることが必要。

作成するライブラリには必ずlib接頭文字が付いていないとリンクできません。

これにてShared Objectによるライブラリ作成完了。


./test.c

#include <mylib.h>

int main(void){
  mylog("test")
}

#g++ text.c -o test -lmylib

-lオプションで指定するライブラリ名はlib+ライブラリ名.soというオブジェクトファイルをさしている。

#./text

#cat /tmp/mylog.log
test

以上。忘備録。

Ruby on Rails: テーブル間のリレーションシップ has_many belongs_to, has_one, has_and_belongs_to_many

ショッピングサイトを作るにあたっては避けて通れないややこしい概念だけど、調べてみたら面白い。
今回はUserとOrderの関係から探ってみた。

Userは複数のOrderをするので、Userモデルには has_many :orders, Orderモデルにはbelongs_to :userとするのが定石

まずは、Migration

lass CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.string :email

t.timestamps
end
end

def self.down
drop_table :users
end
end

class CreateOrders < ActiveRecord::Migration
def self.up
create_table :orders do |t|
t.string :name
t.integer :user_id

t.timestamps
end
end

def self.down
drop_table :orders
end
end

この二つを作る

#rake db:migration コマンドにてテーブル作成

app/model/order.rb

class Order < ActiveRecord::Base
belongs_to :user
end

app/model/user.rb

class User < ActiveRecord::Base
has_many :orders
end

has_many :orders宣言によってUserクラスには

orders
orders<<
orders.push
orders.replace
orders.delete
orders.delete_all
orders.destroy_all
orders.clear
orders.find
orders.count
orders.size
orders.length
orders.empty?
orders.sum
orders.uniq
orders.build
orders.create

これだけのメソッドが追加される。一対多関係なのでuserからすれば沢山のorderが存在するわけで、それをいじり倒すメソッドが必要というわけだ。

まずはコンソールで検証してみよう

>script/console
Loading development environment (Rails 2.1.1)
>> a = User.new
a = User.new
=> #

まずは空っぽのUserインスタンスが生成される。

>> a.orders
a.orders
=> []

子のArrayクラスを返すがまだ何もない。

>> a.orders.build
a.orders.build
=> #
>> a.orders
a.orders
=> [#]

buildメソッドは新たにorderオブジェクトをを生成し(セーブはしない)userへリンクさせる。

>> a.orders.build
a.orders.build
=> #
>> a.orders
a.orders
=> [#, #]

もう一回buildするともう一個くっつく

>> a.save
a.save
=> true
>> a
a
=> #
>> a.orders
a.orders
=> [#, #]

セーブするとOderオブジェクトたちのuser_idは親のid=4となっていることが分かる。

意外と簡単!

Ruby on Rails のデバッグ

webrickで起動する

#script/server webrick --debugger

対象部分に

debuggerを入れるとそこがブレークポイントとなる。


p [変数名]で変数の参照

list 実行中のスクリプトの表示

c で続行

コードを変更したら再度サーバーを起動し直す必要がある。

rails2.0から使用できる模様。

rails1.2.3から2.0へアップグレードしたけど、1.2.3ベースのコードもそのまま使えている。

config/environments.rbファイルの中のRAILS_GEM_VERSIONで設定するとバージョンごとに異なるふるまいをするようだ。

Active Scaffold + Active Mailer + 絵文字

ActiveScaffoldを入れたRails上で、Auからの絵文字入りメールを処理し、絵文字のコードを画像に変換する。

ActiveScaffoldでは、list_column_helper.rbで定義されているclean_column_valueメソッドで、htmlタグのエスケープを各カラムに対して行うので、ここで一緒に絵文字コードをimgタグに変換するスクリプトを追加すればよい。

AUメールはJISで送られてくる。

1b2442=>漢字コード開始
1b2842=>ASCIIコード開始

AUの絵文字は漢字コードよりもさらに上を使用しているので、漢字コードには引っかからず、1b2442(\$Bうんちゃらかんちゃら)などと表示される。これを抜き出してAU文字コードかどうかを判別すればよい

メールを処理するモデルMailer.rbでメールの本文をjisからUTF-8に変換しているが、絵文字の部分は変換されないために、生のJISコードが記録される。絵文字の中に通常の漢字が混じっていてもきちんと変換されない。

というわけで、メール処理時に絵文字部分を処理する必要がある。

メールの文章をscanメソッドで絵文字のコードにマッチする部分を全部探し出して、それを逐一変換していく。

1.アルファベット 絵文字 漢字

この場合は、\(B絵文字 を \(B絵文字コード\$Bと変換する

2.漢字 絵文字 アルファベット

絵文字 => \(B絵文字コード
\(Bアルファベット=>アルファベット

3.漢字 絵文字 漢字

絵文字 =>\(B絵文字コード 
漢字 =>\$B漢字コードと変換する

もしくは、

2バイトコードか1バイトコードかの条件と漢字か漢字でないかの条件で

if byte_code == TRUE

に変換する

ActiveScaffoldを調べる

activescaffoldプラグインの動作を追った。

app/views/appname/list.rhtml

render :partial => "list"

/vendor/plugins/active_scaffold/default/frontends/views/_list.rhmlt

render :partial => "list_record"

/vendor/plugins/active_scaffold/default/frontends/views/_list_record.rhmlt

column_value = get_column_value(record, column)

render_list_column(column_value, column, record)

この時すでにcolumn_valueはhtmlコードでなく、置換されたものとなっていた。

get_column_value

vendor/plugings/active_scaffold/lib/helpers/list_column_helpers.rb

で定義されている。

get_column_value(record, column) の引数のrecordはまだhtmlから置換されていない状態。

get_column_value関数がhtml置換をしている模様。ちなみにrailsにはh関数があって、それがhtmlからタグ置換を行う。

clean_column_value関数はh関数を呼び出しているだけ。

ということで、

def clean_column_value(v)
 h(v)
end


def clean_column_value(v)
 if v=~ /img src/
  v
 else
  h(v)
 end
end
と変更した。

imgタグはエスケープされなくなった。