2010年2月26日金曜日

css のコメントなんとかしてくれ

 なんで css のコメントは、/* */ だけなんじゃ?
ネストできるならまだしも、ネストできないから、各スタイルに対してどういう意図でデザインしたかが、書きづらい。だから、プログラマブルでもない。ああー、糞長いコメントをついてると、ページのロードに時間がかかるから、コメントなんてどうでもいいのかっ。


/* hoge クラスですよ */
.hoge {
float: left; /* 左寄せ */
background-color: #FFAAAA; /* 淡い赤の背景 */
}


とかあって、こいつを一時的に無効にして様子をみたい…

/*
/* hoge クラスですよ */
.hoge {
float: left; /* 左寄せ */
background-color: #FFAAAA; /* 淡い赤の背景 */
}
*/

しんでください。せめて // のコメントも導入してくれれば

/*
// hoge クラスですよ
.hoge {
float: left; // 左寄せ
background-color: #FFAAAA; // 淡い赤の背景
}
*/

あー、でも、なんか IEのバージョンチェックで // みたいな変なチェックあったかも…

2010年2月25日木曜日

トヨタのリコール騒ぎに関して妄想してみる

 私はプログラマではありますが、ファームウェアの世界とはほぼ無縁なので、ここで書くことは、妄想の域を出ません。はじめに断っておきます。
 今の車は、電子制御の塊で、いろんなセンサから出力される状態が複雑に絡みあって作動しているようです。聞いた話では、600以上のセンサがあるのだとか…。
 ファームウェアでのコーディングは、基本 volatile な世界によるグローバル変数の読み出しによる協調作業で、巷のOSでコーディングするmutex等の排他制御が行われる世界とは一線を画しているようです。そのためコーディング規則もうるさく

// 何かの状態変数
int bar = 0;

void foo() {
bar = 1;
if( hoge ) bar = 0;
}

というような書き方は、ファームウェアの世界ではご法度で、

void foo() {
if( hoge ) bar = 0;
else bar = 1;
}

としなければいけません。
一時的にも、状態変数 bar が 1 でないのに 1 になるのは、正しい状態を表しているとは言えないからです。このような書き方をしてしまうと誤作動につながります。こんな感じのコーディング制約が、山のようにあり、かなり厳格に作られている上に、テストも徹底しているそうです。よって、ちょっとやそっとの事では、勝手に加速をする等と言う事態が起こり得るはずがないのです。

 そこで、フォルトトレーラントという思想で、こんな事が起こっていたのでは?という妄想をしてみます。

 プリウスのような車では、ブレーキを掛けた時に慣性動力から発電を行ってエネルギーの回収を行わなければなりません。これは考え方によっては恐ろしい事です。本当にブレーキが必要な時にブレーキを作動させない可能性があるからです。ここの加減を間違えれば、ブレーキが効かない事態を引き起こしかねません。

 アクセルが踏まれているというセンサがあり、そのセンサからの状態変数 accel が
0 踏まれていない
正数 踏んでいる大きさ
であったとしましょう。何らかの原因でセンサが故障、もしくは、信号の書き込みを妨げられる事態が起こった時に、安全な機構が存在するのか?定期的なタイマで accel = 0 を設定しないと暴走しかねません。このような機構があっても、もし、タイマが故障したら?と考えると恐ろしいです。

 ブレーキが踏まれた時には、accel = 0 にしていれば、加速は止むのでしょうが、車が走行するためには絶えず動力が必要なので、この辺の加減も難しいように思います。

 なんと言っても、600 もの状態変数があれば、その組み合わせは膨大で、ある状態がブレーキの動作を妨げるような事態があり、それを検出するのは容易ではありません。恐ろしいのは、制御装置が定期的に状態変数をポーリングして作動する場合、プログラム上では状態変数をちゃんとブレーキが働くよう設定していても、ポーリングする時だけ状態変数がブレーキが働かないような値になっているかもしれないって事が有り得そうです。

 トヨタさんの噂話を聞くと、あるタイミングで、ある部品が故障した場合、安全な方向に壊れる(倒れる)の?といったところまで要求されるそうです。という事なので、生半可な事では、ブレーキが効かずに加速し続けるという事態が起こりそうもありません。

 しかし、機械制御と電子制御は勝手が違うと思うのです。ここまで複雑な電子制御になった今、フォルトトレーラントなシステム設計という研究が、もっと必要なのでは?などと考えてしまいました。

cakephp modelをいじる

cake の model.php をいじくる…。

function __call($name, $params) {
$names = explode('_',$name);
$cnt = count($names);
if( $cnt >= 2 ) {
if( $names[0] == 'find' ) {
if( $names[1] == 'all' ) return $this->find( 'all', $params );
if( $names[1] == 'first' ) return $this->find( 'first', $params );
if( $names[1] == 'count' ) return $this->find( 'count', $params );
if( $names[1] == 'list' ) return $this->find( 'list', $params );
if( $names[1] == 'threaded' ) return $this->find( 'threaded', $params );
if( $names[1] == 'neighbors' ) return $this->find( 'neighbors', $params );
}
}
throw new Exception('Unknown method for Model::' . $name);
}


これで、


Model->find( 'first', ... );
// が
Model->find_first( ... );


で動くようになる…。発展させていけば、結構面白い事ができそう。

2010/03/06 追記:findBy メソッドあるじゃん orz...

cakephp jscalendar で ExformHelper

Rails activescaffold の activecalendar のように、カレンダをなんとかしてぇ。というコンセプトで書いてみました。

ヘルパ exform.php っす。

<?php
class ExformHelper extends FormHelper {
var $helpers = array('Html','Javascript');
/**
* Returns a set of SELECT elements for a full datetime setup: day, month and year, and then time.
*
* Attributes:
*
* - 'monthNames' If set and false numbers will be used for month select instead of text.
* - 'minYear' The lowest year to use in the year select
* - 'maxYear' The maximum year to use in the year select
* - 'interval' The interval for the minutes select. Defaults to 1
* - 'separator' The contents of the string between select elements. Defaults to '-'
*
* @param string $fieldName Prefix name for the SELECT element
* @param string $dateFormat DMY, MDY, YMD or NONE.
* @param string $timeFormat 12, 24, NONE
* @param string $selected Option which is selected. -> Not used
* @param string $attributes array of Attributes. -> Equals to options
* @param bool $showEmpty Whether or not to show an empty default value.
* @return string The HTML formatted OPTION element
*/
function dateTime($fieldName, $dateFormat = 'YMD', $timeFormat = '24', $selected = null, $attributes = array(), $showEmpty = true) {
// dateFormat が DMY になってしまい、SQL での更新で例外が発生してしまう
// だから、ハードコード
//if( $dateFormat == 'DMY' ) {
// $dateFormat = "%d/%m/%Y";
//} else if( $dateFormat == 'MDY' ) {
// $dateFormat = "%m/%d/%Y";
//} else {
$dateFormat = "%Y/%m/%d";
//}
$edit_id = $this->domId($attributes);
$img_id = $edit_id['id'] . "-trigger";
$cal_img = $this->Html->image("calendar.png", array("alt"=>"calendar","id"=>$img_id));
$out = $this->text($fieldName, $attributes) . $cal_img
. $this->Javascript->codeBlock(
'Calendar.setup({'
. ' button: "' . $img_id . '",'
. ' inputField: "' . $edit_id['id'] . '",'
. ' ifFormat: "' . $dateFormat . ' %H:%M:%S",'
. ' dfFormat: "' . $dateFormat . ' %H:%M:%S",'
. ' showsTime: true,'
. ' time24: ' . (($timeFormat == '12') ? 'false' : 'true')
. '});'
);
return $out;
}

}
?>




コントローラに


var $helpers = array('Html', 'Form', 'Exform', 'Javascript');

ってやって、ビューには

echo $exform->input('limit_date');

とかで使います。もちろん、レイアウトファイルのヘッダには

echo $html->css('jscalendar-1.0/calendar-win2k-cold-1');
echo $javascript->link('jscalendar-1.0/calendar');
echo $javascript->link('jscalendar-1.0/lang/calendar-ja');
echo $javascript->link('jscalendar-1.0/calendar-setup');

を忘れずに…。

2010年2月24日水曜日

blogger 調子悪い

 なんかしらんが、今度は、BLOG_EditorResources' is undefined というエラーで WYSIWYG エディタが逝ったまま戻ってこない…。しょうがないので、前のバージョンのエディタに戻した。こうなる前に、気になった事と言えば、ペーストしたテキストの中に javascript のコードが紛れていた事だ。前にも同じような現象を体験している。
 ひとつ言える事は、javascript は、あまりにもデリケートすぎる事だ…。もうちょい、デベロッパーよりに改善されてもいいのではないか?

cakephp inflector.php 修正


function word_pluralize($word) {
$_this =& Inflector::getInstance();
if (!isset($_this->pluralRules) || empty($_this->pluralRules)) {
$_this->__initPluralRules();
}
if (isset($_this->pluralized[$word])) {
return $_this->pluralized[$word];
}
extract($_this->pluralRules);
if (!isset($regexUninflected) || !isset($regexIrregular)) {
$regexUninflected = __enclose(implode( '|', $uninflected));
$regexIrregular = __enclose(implode( '|', array_keys($irregular)));
$_this->pluralRules['regexUninflected'] = $regexUninflected;
$_this->pluralRules['regexIrregular'] = $regexIrregular;
}
if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
$_this->pluralized[$word] = $word;
return $word;
}
if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
$_this->pluralized[$word] = $regs[1] . substr($word, 0, 1) . substr($irregular[strtolower($regs[2])], 1);
return $_this->pluralized[$word];
}
foreach ($pluralRules as $rule => $replacement) {
if (preg_match($rule, $word)) {
$_this->pluralized[$word] = preg_replace($rule, $replacement, $word);
return $_this->pluralized[$word];
}
}
}

function pluralize($words) {
$_this =& Inflector::getInstance();
$camelize = false;
if( preg_match('/[A-Z]/', $words, $regs) ) {
$words = $_this->underscore($words);
$camelize = true;
}
$word_array = explode('_',$words);
$cnt = count($word_array);
if( $cnt ) {
$word_array[$cnt-1] = $_this->word_pluralize($word_array[$cnt-1]);
}
$result = implode('_',$word_array);
unset($word_array);
if( $camelize ) {
$result = $_this->camelize($result);
}
return $result;
}


参考:CPA-LABテクニカル

ついでに、information を $coreUninflectedSingular と $coreIrregularSingular に追加した。ちゃんと入ってました。
修正報告入れた方が良いのだろうか?微妙な感じもする。

追記:あかん、他が動かなくなる…。もうちょいテストしないと…
追記:バグ修正。+いろんな場所から、多様な使われ方をしているようで、それに対応できるよう修正を入れ直した。

2010年2月22日月曜日

cakephp FormHelper のリンク生成、たぶんバグ

/cake/libs/view/helpers/form.php 180行目あたり
if (empty($options['url']['controller'])) {
        if (!empty($model) && $model != $defaultModel) {
          $options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model));
        } elseif (!empty($this->params['controller'])) {
          $options['url']['controller'] = Inflector::underscore($this->params['controller']);
        }
      }
編集時の form の submit 先のURLを自動生成している。基本は、$model つまり、モデル名から命名規則に従っているのだが、モデルで、$useTable = 'hoge' を指定した場合は URLが見当違いになってエラーとなる。


 information の複数形は information であり、それの省略 info を使用したら 複数形が infos だと仰るのだ…。正直 form.php のこの部分だけでは修正できそうにない感じがする。テーブル名を直すことにするよ…チクショウ…。

追記:view 内でお茶を濁した
<?php echo $form->create('HogeInfo', array('url'=>array('controller'=>'hoge_info')));?>

2010年2月18日木曜日

cakephp

 今コーディングしているシステムは、php がベースで、まじめに書いてたら終了する気がしないので、cakephp を利用する事に決めました。
 で、cakephp をいじくってます。こういう事もあろうかと、DBはActiveRecordの流儀に則って設計しておいたので、よかった…。しかし、それでも終わる気がしない…。

CSS のデザインで、default.ctp の要素に直接 style を埋め込んだ場合と、link rel="stylesheet" で hoge.css を指定した場合と、ファイル名を hoge.generic.css に指定した場合の、3パターンで、レイアウトが異なるという怪現象で、ひっかかったり。

 地図を載せている関係上、ページの更新はAjax でやらないとまずいのだが、$paginator->options(array('update' => 'content', 'indicator' => 'spinner')); を指定するタイミングが、default.ctp 内では早すぎて、view の index.ctp 等の中で指定しないとダメだったり。

 ちょっとした事で、はまってます。

2010/02/23 追記: css の件は、たんなるタイポでした。まんまコピーしたつもりなのに、なんでゴミが紛れてんねん…。HTML Validator は重要です…(何をいまさら)。

2010年2月17日水曜日

xpressive いい!

 いやー、boost::xpressive 便利ですねー。白状すると、正規表現は苦手科目でして、どうにも使い方がいまひとつわかんなったんですよねー。だから、正規表現で検索して、とある部分にマッチする部分だけを抜き出すには、どないしたらええねーーーーん。うゎわーーーーん。だったんですよ…。これ、内緒の話ね。
 わかってしまえば、何のことはない。() で囲んだ部分は、マッチした中から、更に配列形式で取り出せたんですね…。もう、感動もんです。

#include <boost/xpressive/xpressive.hpp>
#include <string>
#include <iostream>

int main() {
  std::string str = 
    "fuga 2005/01/32 21:22:54 hoge 2003/12/03 13:21:33 fuga=\"hoe--\" <hohoho>";

  boost::xpressive::sregex r = boost::xpressive::sregex::compile( 
    "hoge (\\d\\d\\d\\d)\\/(\\d\\d)\\/(\\d\\d) (\\d\\d):(\\d\\d):(\\d\\d)" 
  );
  boost::xpressive::smatch m;
  if( boost::xpressive::regex_search( str, m, r ) ) {
    std::cout << m[1] << "/" << m[2] << "/" << m[3] << " ";
    std::cout << m[4] << ":" << m[5] << ":" << m[6] << std::endl;
  }

  return 0;
}

追記:くーっ、隊長いつの間にこんな記事を… orz

2010年2月16日火曜日

雪あかりの路 2010

続いて、小樽雪あかりの路でございます。
今年は、寒くて風邪ひいた…。

雪祭り2010

今年2010の雪祭り・・・







うちの坊ちゃんは、ウルトラマンが気にいった様子…。ウルトラマン見た事ないんだけどね…(^^;

2010年2月11日木曜日

Google 雑感 Buzz

 「イノベーションの神話」によると、イノベーションの条件の1つに、「移行コストが低い事」というのがある。GMail から Buzz への移行コストは、そこそこ低いと言える。そういう意味では、Buzz は、そこそこ使われるようになるかもしれない。問題は、Twitter 的要素に GMailは最適か?である。GMail 以外に専用の入り口を用意すべきであろう。
 Google Wave についても言及しておくと、Git によるリアルタイム性の強いリポジトリ・ドキュメント・システムじゃねぇの?というのが、今のところ、私が持っている印象である。いや、Wave なんてビデオの紹介でしか見たこと無いんだけどね…。
 私は、Twitter さえ使うのを拒否しているので、Buzz を使わないだろう。ちょっと覗いてみたが、あれを公開しろ、公開しろ、おまえのデータを公開しろ、と、もう、やりたくない汁が充満してしまった。何を公開して、何を公開しないかは、俺がコントロールする。ちなみに、Facebook も MySpace も Mixi もやらないし、やる予定もない。

2010年2月10日水曜日

天安門事件セール

 ふと、TechCranch の記事を見ていて閃いた。いくら中国でも、全部を人手を介して人力ファイヤーウォール登録するのは、無理だ。そして、この時代に、情報を抑えこもうとするアホさ加減…。中国の人権問題は、日本のワーキングプア問題とリンクしているのだ。見過ごしには、できない。
 そこで、みんなで「天安門事件」って、文字を書いてしまえば、いいんじゃね?

  「天安門事件」って書いちゃえば、面白くね???

 どこにもアクセスのしようが無い・・・と、そんなくだらない事を思いつき、実行に移してみました。

2010年2月7日日曜日

mimetic が密かに気になる

 今、密かに気になっているライブラリがあります。
mimeticという、MIMEのライブラリです。C++で、この辺の事を処理しようと思ったら、相当しんどいです。有償のライブラリは探せばあるんでしょうけど…。VC で使おうと思ったら、きじねこさんの stdint.h が必要です。

copy config_win32.h config.h

とした上で、HAVE_STDINT_H を定義しないとコンパイル通りません。

サンプルには、

#include <stdint.h>

の1行を加えてやる必要があります。

2010年2月3日水曜日

strict week ordering?

 久々に代数学の教科書を引っ張り出してきた…。

順序集合(半順序)の条件は

a) 反射律 x <= x
b) 非対称律 x <= y && y <= x -> y == x
c) 推移律 x <= y && y <= z -> x <= z

であり、これに

d) (x <= y || y <= x) が真

という条件が加われば全順序集合という事になる。

Strict week ordering 聞いた事が無かったが、これによると


a) 反射律の対偶?と呼ぶべきか、非反射律と呼ぶべきか? !(x < x)
b) 非対称律の対偶(なんて表現すれば…)? x != y -> (x < y || y < x) && !(x < y && y < x)
c) 推移律(変形) x < y && y < z -> x < z
d) !( x < y || y < x ) && !( y < z || z < y ) -> !( x < z || z < x )

全順序集合から == を取り除いたものという感覚が一番しっくりするかも…。

比較可能であれば、必ず x < y || y < x が成立し、比較不可能であれば !( x < x ) より常に false となる。

で、確かに、なんて訳せばいいのかは、わかんねーです。

追伸:Blogger のエディタが文中の < & > を正しく扱えなくて、何度も書き直した。イライラが続くときは、こんなもんか…。
追記 2010/02/04:Strict weak ordering (b) の条件を強化
weak の意味は、不等号 < という意味に近いのかな?と思った。そうすると、完全比較順序集合という訳が妥当かもしれない。

ぬがー

タスク多すぎて、キレそう…

boost::asio で serial通信 (PATLITE)

仕事で、パトライトを制御する事になった。せっかくなので、boost::asio を使ってみた。


#include <boost/asio.hpp>
#include <iostream>
#include <iomanip>

#define PATLITE_COMMAND_

#define PATLITE_CMD_BIT 0x30
#define PATLITE_RED_ON 0x01
#define PATLITE_YELLOW_ON 0x02
#define PATLITE_GREEN_ON 0x04
#define PATLITE_BUZZ_SHORT 0x08
//
#define PATLITE_BUZZ_LONG 0x01
#define PATLITE_RED_BLINK 0x02
#define PATLITE_YELLOW_BLINK 0x04
#define PATLITE_GREEN_BLINK 0x08

void write_hex( const char* p, size_t len ) {
for( size_t i = 0; i < len; ++i ) {
std::cout << ":" << std::hex << std::setw(2) << (int)p[i];
}
}

int main() {
char start_rbuf[ 7 ] = { 0x40, 0x3f, 0x3f, 0x31, PATLITE_CMD_BIT | PATLITE_RED_BLINK | PATLITE_BUZZ_LONG, PATLITE_CMD_BIT, 0x21 };
char start_ybuf[ 7 ] = { 0x40, 0x3f, 0x3f, 0x31, PATLITE_CMD_BIT | PATLITE_YELLOW_BLINK, PATLITE_CMD_BIT | PATLITE_BUZZ_SHORT, 0x21 };
char start_gbuf[ 7 ] = { 0x40, 0x3f, 0x3f, 0x31, PATLITE_CMD_BIT | PATLITE_GREEN_BLINK | PATLITE_BUZZ_LONG, PATLITE_CMD_BIT, 0x21 };
char stop_buf[ 7 ] = { 0x40, 0x3f, 0x3f, 0x30, 0x3f, 0x3f, 0x21 };
char buf[ 8 ];

try {
boost::asio::io_service service;
boost::asio::serial_port port( service );
std::cout << "open COM1" << std::endl;
port.open( "COM1" );
std::cout << "set up baud_rate 9600" << std::endl;
port.set_option( boost::asio::serial_port_base::baud_rate( 9600 ) );
port.set_option( boost::asio::serial_port_base::character_size( 8 ) );
port.set_option( boost::asio::serial_port_base::stop_bits() );
port.set_option( boost::asio::serial_port_base::parity() );
port.set_option( boost::asio::serial_port_base::flow_control() );
std::cout << "write 1"; write_hex( start_rbuf, 7 ); std::cout << std::endl;
port.write_some( boost::asio::buffer( start_rbuf, 7 ) );
std::cout << "read 1" << std::endl;
port.read_some( boost::asio::buffer( buf, 1 ) );
std::cout << "result: " << std::hex << (int)buf[0] << std::endl;
Sleep( 2000 );
std::cout << "write 2"; write_hex( start_ybuf, 7 ); std::cout << std::endl;
port.write_some( boost::asio::buffer( start_ybuf, 7 ) );
std::cout << "read 2" << std::endl;
port.read_some( boost::asio::buffer( buf, 1 ) );
std::cout << "result: " << std::hex << (int)buf[0] << std::endl;
Sleep( 2000 );
std::cout << "write 3"; write_hex( start_gbuf, 7 ); std::cout << std::endl;
port.write_some( boost::asio::buffer( start_gbuf, 7 ) );
std::cout << "read 3" << std::endl;
port.read_some( boost::asio::buffer( buf, 1 ) );
std::cout << "result: " << std::hex << (int)buf[0] << std::endl;
Sleep( 2000 );
std::cout << "write 4"; write_hex( stop_buf, 7 ); std::cout << std::endl;
port.write_some( boost::asio::buffer( stop_buf, 7 ) );
std::cout << "read 4" << std::endl;
port.read_some( boost::asio::buffer( buf, 1 ) );
std::cout << "result: " << std::hex << (int)buf[0] << std::endl;
std::cout << "end" << std::endl;
} catch( std::exception& e ) {
std::cout << e.what() << std::endl;
}
return 0;
}



シリアル通信のオプションは、キッチリ指定しないといけないようです。デフォルトであろうと指定しないと動作しなかった。

mongrel_cluster prefix AbstractRequest (NameError) 備忘録

 また、検索しそうなので備忘録として記録する。

mongrel_cluster + mod_proxy_balancer の組み合わせで、prefix を指定すると、エラーが出るようになった。原因は、Rails の内部仕様が変更された事による。

/usr/lib64/ruby/gems/1.8/gems/mongrel-1.1.5/lib/mongrel/rails.rb
に修正を施す。

ActionController::AbstractRequest.relative_url_root = ops[:prefix] if ops[:prefix]

という部分を

if ops[:prefix]
if ActionController::Base.respond_to?('relative_url_root=')
ActionController::Base.relative_url_root = ops[:prefix]
# new way to set the relative URL in Rails 2.1.1
else
ActionController::AbstractRequest.relative_url_root = ops[:prefix]
end
end

 とする。

参考URL
LANKHMAR
mongrel rubyforge