2012年11月1日木曜日

売上1/2ダウン↓↓をアジャイルサムライが救うっ( ー`дー´)!?

カロリー1/2 うれしいですよね?
ヽ(´ー`)ノ<うれしいうれしいー!
価格1/2 たのしいですよね?
ヽ(´ー`)ノ<たのしいたのしー!

しかし、課の売上が1/2となるとうれしくも、たのしくもありません...
むしろ深刻です。
その深刻な事態がウチの課でおこったのです。
去年の売上がおととしの半分以下でした。

( ・`д・´)<あーあ、そりゃタイヘンですねーなんでそうなったんですか??

悲しいかな...
お客様頼みで、仕事を待つ以外何もしてこなかったことが原因。
ってことは、逆に今期は、
『待つことなんてせずに果敢にチャレンジしなければならない』
わけですっ!

アジャイル開発を導入しようと、、、
そこで注目したのが『アジャイル開発』。
以前からずっと導入したかったんですが、なかなかそれができずにいました。
なぜかというと、『テスト自動化』が必要なんです。
それをとりあえず課になじませようとしました。

いろいろな書籍をあたり、
調査したんですが、
なかなか合うUNITテストのツールがなく、
はては『レガシーコード改善ガイド』に、
( ・`д・´)<「オブジェクト指向じゃなきゃ無理っすよ」
といってるも同然にオブジェクト指向前提で展開され、
『全システムをオブジェクト指向開発してるか?』といわれれば、
徹底できてないウチは、
はしごをはずされましたwww

|||ひゅー
ヽ(´ー`)ノ

とりあえず、やってみる。
そこでどうしたらいいものか考えあぐねていたんですが、
一大事ってことで、
(1)ユーザが欲しいものをちゃんと届けること
(2)開発を素早く行うこと
ということを目標に掲げてアジャイルの強行導入に踏み切ろうとしたのです。


欧米のITの強さとは!【情報処理推進機構(IPA)】
じつは時を同じくして、偶然にも『独立行政法人 情報処理推進機構(IPA)』が、
2012年6月11日にあるレポートを出しています。
『非ウォーターフォール型開発の普及要因と適用領域の拡大に関する調査報告書』
というものです。

(イ)欧米のIT企業の強さの秘密の一つがアジャイル開発であるとした上で、
(ロ)日本のIT企業にアジャイルが根付いていない理由と
(ハ)今後日本にアジャイル開発を根付かせるにはどうしたらいいのかの提案
がなされていました。

日本でアジャイルできるのか?
欧米ではユーザと近いところで開発者が開発しています。
だから、アジャイルが適用しやすいんですが、
日本の場合、下請け下請けに出して、ユーザと開発者が遠く、
アジャイルが馴染まないわけです。

( ・`ω・´)<でも、下請け下請けに出すのって大手の話ですよね?

大手ではない場合はどうか...
一方で、アジャイル開発は最初にやることをカチッカチに決めません。
だから、顧客との信頼が必要になります。
でも、出来立てのベンチャーなんかはその信頼を築くのに一苦労です。

しかし、それこそがウチの課を立て直す宝刀なのですっ☆
ウチはエンジニアを抱えていて、社内で開発しています。
しかも、歴史が長い分、他の開発会社に比べて顧客との信頼が厚いんです。
営業なんか「え?!」ってことでも、お客さんに無理言って通したりしますし。
だから、ウチも無茶言われたりするんですが、
その関係こそがウチの強みなわけです。

日本の他の開発会社が足踏みしてるうちに、
アジャイルを導入しちゃって、
(1)ユーザが欲しいものをちゃんと届けること
(2)開発を素早く行うこと
ができる会社として、アジャイル開発をウチの強みにしてみましょうってことです。

アジャイルの起源は、野中郁次郎
レポートの中にも書かれているんですが、
アジャイル開発でメインになっているスクラムは、
日本の経営学者の野中郁次郎さんが1986年に書いた論文、
『the new new product development game』がもとになっています。

それはjapan as No.1だった1980年代に、
日本の製造業の強さとは何かを解き明かすため、
有名な経営学の雑誌『Harvard Business Review(HBR)』から依頼をうけた野中郁次郎さんが、
ホンダやキャノン等々日本の製造業への綿密な調査を通じて書いた論文です。

自律性の必要性やチームでの仕事の大切さを、
「若干平均27才のホンダのチームが自動車の新しいコンセプトから打ち出しヒットさせた」こと
など事例を提示しながら書かれていました。
(それだけではないですが、この解説がメインではないので他に譲りますね。)

経営学でいえば、有名なミンツバーグさんも、
長期的な計画をたててやっていくやり方には否定的なようです。

ウチの会社はどちらかというと古いタイプの企業なので、
かつての日本の製造業のやり方は馴染むのではないかと考えました。
japan as No.1だった製造業だけではなく、
欧米のIT企業も採用して成功しているという実績があったことも導入したい理由でした。

アジャイルサムライを教科書にして
さて、思い立ったが吉日ってことで、
さっそくアジャイルの書籍のなかでも好評の『アジャイルサムライ』を購入。
ちょうど巡ってきた事業部内での朝礼当番で、
今まで書いたことを手短に説明し、
最後に、

( ・`д・´)<ウチの課の戦略的支柱は営業であり、すなわちUさん、あなたですよっ!!!

と啖呵を切りました。わーww
ここからアジャイル開発を課に浸透させるべく、
サムライ先生との長い旅が始まりましたでござる( ー`дー´)

勉強会から始まるアジャイル開発の導入は、

製造業でのジャスト・イン・タイムや、
経営学でのミンツバーグさんや野中郁次郎さんの主張、
そしてシステム開発のアジャイル、
まったく別の分野から、同じような思想がでてきています。
しかも、それより以前にあった計画的に進めることを批判した上で、
それの代替案として。
このことの説得力たるやって感じです。

2012年3月8日木曜日

クロスドメインでXMLHttpRequestを送るときの逃げ道≡(;´Д`)ノ

クロスドメインでHTTPヘッダを送信するってこと
( ゚Д゚)<POSTでもGETでもなく、HTTPヘッダですよ!

おぅふ、こんなやっかいなこと言い出すなんて..._ノ乙(、ン、)_
後悔先に立たず。ありますよね?
( ・`д・´)<あるあるー!

今回はシステム間の遷移のお話です。
『ポートもドメイン名すらも違うWebシステムに任意のHTTPヘッダを送信する』
にはどうしましょうってことです。
状況として
振り返れば数週間前...( ´Д`)。oO(

(゚Д゚)<そちらのシステムから、うちのシステムに遷移させてもらえませんか?
はじまりはこの一言でした。
言い出したのは、うちの最大顧客の小会社でシステム開発しているS社。
無視するわけにはいかないし、
ただ遷移するだけなら簡単そうなので、
ヽ(´ー`)ノ<大丈夫ですよ!へっちゃらです。
って営業さんが返事してました。
(し、僕も大丈夫だと思ってました。)
やりたいことって?
要望を大雑把に言うと、
(1)うちのシステムにユーザがログイン
(2)あるボタンをクリック
(3)S社の開発したシステムに遷移。
ってことです。

普通にリンクはっただけでは、ユーザの識別ができないので、
ユーザを識別するコードを、
S社が用意してくれるアルゴリズムにしたがって暗号化して、
それをS社のシステムに送信するってことでした。

暗号化アルゴリズムもくれるっていうし、
POSTかGETで送信すれば全然たいしたことないっすよね。
って思ってました。
<a href="http://sss/xxx?user=0001">S社のシステムに遷移!</a>

とか、
みたくね。
直前になって...データはHTTPヘッダで送って
で、S社のシステムが本番反映をむかえる1日前、この一言がでたのです。

( ゚Д゚)<POSTでもGETでもなく、HTTPヘッダですよ!
正直。
なにいってんだ(゚Д゚)ゴルァ!!
って思いました。
S社はPOSTででもGETでもなく、
HTTPのヘッダに付加してリクエストを送信してほしかったのです。

[HTTPのヘッダ]
Accept-Language: ja
Referer: http://xxxxxxxx/ooooo.html?44
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible;...
USER: 0001

というのを期待しているようでした。

(゚Д゚≡゚Д゚)<素直にGETでおくれよー!
って。
しかしそこは最大顧客の小会社。どうにかしなければなりません。
『うちの方法と違うので、送信方法おしえてくれませんか?』
とS社にも協力を要請し、
どうしようかと調査開始。
制約~HTTPヘッダの付加とクロスドメイン~
とりあえず制約として、
(1)クライアントで任意のHTTPヘッダを付加する。
(2)ポートもドメインも違うWebシステムにリクエストを送信する。
の2点がありますが、
この二つが互いに足をひっぱりあいます。

任意のHTTPヘッダをクライアントで付加してリクエスト送るためには、
XMLHttpRequestを使う必要があります。
しかし、ポートもドメインもうちのシステムと違うシステムへリクエストを送信するため、
クロスドメイン制約にひっかかります。

一方、普通にGETで送れるならば、
anchorタグに href="http://xxxxx/oooo.jsp?user=0123" とかって指定すれば遷移します。
POSTでsubmitしてもいいですし。
でもそれだとHTTPヘッダは付加できません。

((ミ・♀・ミ)) くまった。

ところで、いいだしっぺのS社はというと、
『サーバでのHTTPヘッダの取得方法』とか、
『サーバでHTTPレスポンスにヘッダを設定する方法』とか、
ちょwwよくわかってないんじゃないのww
って返答ばかりが返って来ました...
いろいろな誤解~HTTPレスポンスでもなく、JSONPでもない~
誤解1
ヽ(´ー`)ノ<HTTPヘッダならいつもサーバで付加してるやん!

( ・`д・´) はいこれはS社と同じ誤解ですね。
HTTPにはリクエストとレスポンスがあります。
誤解1の場合はレスポンスのHTTPヘッダのお話です。

クライアント<-----【HTTP】----- サーバ

こんな感じですね。
たとえば、みんないつも

   Response.ContentType="application/octet-stream;name=file.pdf"
   Response.AddHeader "Content-Transfer-Encoding","base64"
みたいな感じでレスポンスのヘッダに付加してるから、
コレじゃない?って思うわけです。
でも、これではないんですね。

クライアント-----【HTTP】-----> サーバ

今回の場合はコレ。リクエストですね。
やり方としては、
具体的にはJavascriptでXMLHttpRequestを生成してヘッダを加えて、送信します。
xmlReq = new XMLHttpRequest();
xmlReq.open("POST","test.php", true);
xmlReq.setRequestHeader("user", inUser);
xmlReq.send(null);


このtest.phpの部分がhttp://xxxxxxになっていたら...
xmlReq.open("POST","http://xxxxxx", true);
とかになっていたら、クロスドメインとみなされて失敗します。もしくはエラーがでます。

誤解2
ヽ(´ー`)ノ<クロスドメインといえば、JSONPとかでできんじゃないの??

( ・`д・´) はいこれは僕が最初勘違いしていました。
これもおんなじ図で説明します。
JSONPは

クライアント<-----【データ】----- ドメインの違うサーバ

こんな感じでドメインの違うサーバからデータを取得する方法なんですね。
今回はこれ。

クライアント-----【データ】-----> ドメインの違うサーバ

しかもHTTPのリクエストに任意のヘッダを追加しないといけないおまけ付きです。
解決方法...ではなく逃げ道≡(;´Д`)ノ
さすがにここまで制約つくと一筋縄ではいかず、
どっちかの制約を緩和する方法が必要になりました。

で、その緩和する方法とは、
『そちらのドメイン名でアクセスできるHTMLファイルをそっちのサーバに置かせて!』
ってことでした。

つまり、S社のサーバに置かせてもらったHTMLから、
XMLHttpRequestでデータを送信しようって魂胆です。
ドメイン名がS社のシステムと同じならクロスドメインにひっかかりません。
図にするとこんな感じ。

ステップは3つ
(1)うちのサーバにあるリンクをクリックして、S社のサーバにうちが置いたHTMLファイルに遷移
(2)javascriptでURL(http://sss/http_header.html#0001)からユーザ情報を取得
(3)XMLHttpRequestを生成し、HTTPヘッダに取得したユーザ情報を付加、送信

(1)うちのサーバでやるのはリンクをはることだけです。URLのおしりにユーザ情報を付加して。
ちょうどこんな感じですね。 <a href=”http://sss/http_header.html#0001”>リンク</a> ユーザはこのリンクをクリックして、まんまとS社のサーバにとびます。

(2)つぎにうちがS社のサーバにおいた静的なファイルhttp_header.htmlに遷移します。
ここではonloadかなんかのイベントでユーザの情報を取得します。
location.hashを用いれば取得できます。
たとえばこんな感じで。
var user =  String(location.hash).substring(1) //#よりうしろが取得される。

(3)あとはこれをXMLHttpRequestで送信すればOKです。
このHTMLファイルはS社のサーバからクライアントに送られているので、
S社のサーバにあるシステムに存分にデータを送信できます。
クロスドメインなんかこわくないヽ(´ー`)ノわーい
雑ですが、http_header.htmlの中身です。
<html>
<head>
<script language='javascript'>
<!--

function send(){
  xmlHR = new XMLHttpRequest();
  
  xmlHR.onreadystatechange = function() {
    if (xmlHR.readyState == 4) {
      if (xmlHR.status == 200) {
        var page = window.open("", "", "");
        page.document.open();
        page.document.write(xmlHR.responseText);
        page.document.close();
        window.close();
        
      } else {
        var page = window.open("", "", "");
        page.document.open();
        page.document.write("false
<\/body><\/html>");        page.document.close();      }    }  }    xmlHR.open("POST","main.php", true);  xmlHR.setRequestHeader("USER", String(location.hash).substring(1));  xmlHR.send(null); } --> </script> </head> <body onload="send()"> </body> </html>
たしかに
当初の目的とはずれましたが、
どんな要望でもお手上げ状態ではなく、
何かしらの案を出せるもんだなって自信がつきましたっ( ・`д・´)

2012年2月1日水曜日

windowsサーバでビルドスクリプトを実行(σ・∀・)σ!!

ポチポチポチ...
パラパラパラパラパラパラパラ( ´ー`)ノシ
( ・`ω・´)<これは何の音ですか??
作業手順書の中から今やる作業を見つけてる音ですヽ(´ー`)ノ

ポチポチポチポチポチポチポチ(σ ´ー`)σ
( ・`ω・´)<これは何の音ですか??
GUI使って、テーブルを作成してる音ですヽ(´ー`)ノ

ブーブーブー( ´ー`)ノ
( ・`ω・´)<これは何の音ですか??
手順どおり更新したのに、なんでかエラーが出ている音ですヽ(´ー`)ノ

(´・ω・`)...

GUIで楽してみても
windowsサーバのシステムを作っていると、
GUIが優れてるんで、ぽちぽちした方が簡単だよ? >ヽ(´ー`)ノ

( ・`д・´)<でもほら、本番で作業がもれてエラーでてるじゃない!!

もうダメ!!ビルドスクリプト作ってそれで構築してっ!

ええー(´Д`)ノ

( ・`д・´)<
【開発環境】⇒【テスト環境】⇒【仮本番環境】⇒【本番環境】
と、そのスクリプトを何度も実行することで、
信頼性がアップしますっ。
どんな作業したのかも、簡単にのこせますし。


実際こんな流れでビルドスクリプトを提案。
Javaでant使ってた身としてはいささか手作業は不思議でした。

windowsでのビルドスクリプトって
選択肢としては、
(1)コマンドプロンプト
(2)VBScript
(3)PowerShell
があります。
非力ではありますが、どこでも使えて簡単に実行できる、
コマンドプロンプトで『build.bat』みたいなのを書いて、
サーバで実行していました。
今回はそのお話。

マシンの種類でビルドスクリプトは分けていて
DBサーバとWebサーバは違うマシンだったので、
それぞれで実行(σ・∀・)σ!
DBサーバでやったのは、
テーブルの作成
列の追加
ビューの作成
テーブルのバックアップ
データの挿入

とかでしたけども、
だいたいはSQLを動かすだけ。
つまりはコマンドプロンプトから任意のSQLが実行できれば、
ビルドスクリプトとしては十分でした。

Webサーバでやったのは、
ディレクトリの作成
権限の付与
ファイルのコピー

とかですね。
こんな感じの
こんな感じのディレクトリ構成で、
sql:実行するSQLファイルがある場所
backup:スクリプト実行前にとったバックアップを保存しておく場所
log:実行結果のログファイルを残す場所
insert:新たにDBのテーブルに追加するデータが入っている場所
DBサーバのビルドスクリプトの例として
それぞれの例はこちらっ↓↓
set dbserver=SERVER
set dbuser=USER
set dbpass=PASS

echo build start ---------------------------------  >> ./log/build.log
echo build実行  >> ./log/build.log
echo %time% %date%  >> ./log/build.log

rem -- table1テーブルのバックアップ
bcp "select * from db1.schema1.table1 where type='A'" queryout  ../backup/table1.bak -n -T -S %dbserver% -U %dbuser% -P %dbpass% >> build.log

rem -- テーブルを作成するSQL実行
sqlcmd  -U %dbuser% -P %dbpass% -i ./sql/createTable.sql -o ./log/result_createTable.log
rem -- データを追加するSQL実行
sqlcmd  -U %dbuser% -P %dbpass% -i ./sql/insertID.sql -o ./log/result_insertID.log
rem -- テーブルに列を追加するSQL実行
sqlcmd  -U %dbuser% -P %dbpass% -i ./sql/addColumn.sql -o ./log/result_addColumn.log

rem ------- table2テーブルにデータを追加
bcp db1.schema1.table2 in ./insert/table2.bak  -n -T -S %dbserver% -U %dbuser% -P %dbpass% >> build.log
echo table2テーブルにデータを追加 >> ./log/build.log

echo %time% %date%  >> ./log/build.log
echo build end  ---------------------------------   >> ./log/build.log
もっと実際は複雑ですが、骨組みだけを取り出せばこんな感じ。
set dbserver=SERVER
こんな感じで使いまわすところは変数に格納します。
いつ、どれくらいで実行したのかを記憶しておくために
echo %time% %date% >> ./log/build.log
で時間をログに出力。
たとえば実行されるSQLとは
たとえば実行するSQLファイルはこんなことが書かれていたりします。

テーブル作成
-- table_one
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'table_one') AND type in (N'U'))
BEGIN
CREATE TABLE table_one(
    one_id      nvarchar (20)  NOT NULL
  , one_name    nvarchar (100) NOT NULL
  , created_on  datetime
  
  ,  CONSTRAINT [PK_table_one] primary key clustered
 (
  one_id ASC
 )
)
END
GO

-- table_two
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'table_two') AND type in (N'U'))
BEGIN
CREATE TABLE table_two(
    two_id      nvarchar (20)  NOT NULL
  , two_name    nvarchar (100) NOT NULL
  , created_on  datetime
  
  ,  CONSTRAINT [PK_table_two] primary key clustered
 (
  two_id ASC
 )
)
END
GO
これでテーブルがひとつ増えて、実行するSQLが追加されても、同じファイルを実行できます。

もしくは、不具合対応のための
while (
          ( select count(*) from db_one.schema_one.users
            where user_id is null
            and   user_name is not null 
          ) > 0
      ) 
begin

    update db_one.schema_one.users
    set user_id = (
                             select 'US' + right('000000' + cast(key_number + 1 as nvarchar),6) 
                             from db_one.schema_one.key_table
                             where key_type = 'user_id' 
                        )
    where row_no = 
    (
        select max(row_no) from db_one.schema_one.users
        where user_id is null
        and   user_name is not null
    )

    update db_one.schema_one.key_table
    set key_number = key_number + 1
    where key_type = 'user_id'

end

--『user_id』がnullで『user_name』が書きこまれていることがイレギュラーなこととして。
こんなだったり。

DBのデータを入れたり、出したりは、bcpコマンドを使います。
マシンにもよるかと思いますが、数百万行のデータでも余裕で実行できました。

SQLの実行は、sqlcmdでSQLファイルのあるパスを指定。
どこに何があるのか管理しやすくするため、ファイルは分けてあります。
Webサーバでのビルドスクリプト
set hname=WEBSERVER

echo build start ---------------------------------  >> ./build/build.log
echo directory作成  >> ./build/build.log
echo %time% %date%  >> ./build/build.log

rem ------- tmp作成
if not exist D:\dev\tmp     mkdir D:\dev\tmp >> ./build/build.log
echo y|cacls D:\dev\tmp /E /G iusr_%hname%:c >> ./build/build.log
echo tmp OK >> ./build/build.log

rem ------- img作成
if not exist D:\dev\img     mkdir D:\dev\img >> ./build/build.log
echo y|cacls D:\dev\img     /E /G iusr_%hname%:c >> ./build/build.log
echo img OK >> ./build/build.log

echo build end  ---------------------------------   >> ./build/build.log
作成するディレクトリがなければ、作成します。
if not exist D:\dev\tmp mkdir D:\dev\tmp
あとは権限を付与。
iuserはマシン名を持つことが多いので、「iusr_%hname%」としています。
cacls D:\dev\tmp /E /G iusr_%hname%:c
これだと確認を求められるので、
パイプで「y」を送っておいて、その作業を代行します。
echo y|cacls D:\dev\tmp /E /G iusr_%hname%:c

まあだいたいはこんな感じですね。

これよりもっと複雑になってくると、
普通にVBScriptを書いて実行した方が現実的です。

2012年1月25日水曜日

>/dev/null 2>&1になんか納得いかないあなたへ

>/dev/null 2>&1とは?
>/dev/null 2>&1は、コマンドの結果を表示させないときに使う定石です。
 軽く解説すると、
コマンドが正常に処理されて、標準出力に結果が表示されるはずのときも、
コマンドが失敗して、標準エラー出力に結果が表示されるはずのときも、
どっちもひっくるめて、/dev/nullにリダイレクトして、
表示させずにおきましょうってことですね。

え?でもこれって、
command 2>&1 >/dev/null
のがしっくりこない( ・`д・´)??

その気持はわかります。
では、正しい場合と間違いやすい間違いの場合を、
細かく見て行きましょう。
初期状態として
最初はこういう状態です。
標準出力をファイルにかえる。
先に標準出力をファイルに変更します。
command 1>/dev/null
ということですね。
標準出力はファイルを指すようになります。
標準出力はファイルを指すようになります。
いつもどおりの結果です。
標準エラー出力を標準出力が指している先にかえる。
つぎに2>&1の部分です。
「標準出力はどこを指してるんだろう?」と、
標準エラー出力は標準出力がさしてる先を見に行きます。
標準出力と標準エラー出力はファイルを指すようになる。
その結果、標準出力と標準エラー出力は、
同じところ(/dev/null)を指すようになります。
command 2>&1 >/dev/nullの場合(間違い)
先に標準エラー出力は、「標準出力がどこをさしてるんだろう?」
と見に行きます。
先に標準エラー出力は画面を指す。
標準エラー出力は、今標準出力が指している画面を指すようになります。
次に標準出力はファイルを見に行く
標準出力はファイル(/dev/null)をみにいきます。
標準出力は/dev/null、標準エラー出力は画面
先に標準エラー出力は画面を指すようになっていたので、
画面を指し、
標準出力はファイルを指すようになります。
この場合は、エラーが出た場合は画面に出力され、
( ̄ー ̄)ちーーーん
となります。

さて、2>&1の&の部分ですが、
これはC言語のポインタを考えると理解しやすいです。
1を変数と見立てると、2という変数に1のポインタの値を代入していますね。

2012年1月17日火曜日

redmineからのー、saltと入れ子集合モデルー♪~(´ε` )

redmineを導入しようとして...
軽く始めたことが、自分の習慣も変えるようになることってありますよねー?
( ・`д・´)<あるあるー

 このまえ職場でプロジェクト管理をちゃんとやろうと思い立って、
redmineをいじりはじめましたヽ(´ー`)ノ

オフィシャルっぽいブログもあって、
導入するのにそんなに苦労はしませんでしたが、
これがちょっとした自分のモットーを変えることになったのです。
ちょっとのぞいてみたテーブル
redmine、職業柄どんな風につくられてんだろうって気になったのですが、
Rubyわかんないので、とりあえずテーブル眺めることに。 

まず見たのが『users』テーブル。
作成日付とかって『created_on』って名付けるんだへー(´・∀・`)
と感心していると最後のカラムに気になる名前が

『salt』

 むむ( ・`д・´)
ユーザのテーブルにあるし、
 やはりパスワードを暗号化するときに付加するアレかと。 

つぎにプロジェクト管理ってこともあって、
『projects』テーブルを。

『is_public』ってカラムがありました。
あー僕なら『public_flg』とかってやっちゃうよなーなんて思ってると、
またまた気になるカラムがっ( ・`ω・´)!!!

『lft』と『fgt』 

さすがにこれだけでは断定できませんが、
型がint(11)だってことと、
プロジェクトが親子関係を持ちうるってことを考えると、
やはり、入れ子集合モデルのヤツだなと。
saltと入れ子集合モデルヽ(´ー`)?
saltとは、パスワードとかを暗号化するとき一緒に暗号化することで、
解読されにくくする方法。

入れ子集合モデルとは、
部材表とかみたく再帰的に自分をみていく構造のテーブルを、
もっと早くアクセスするために考案された方法で、
 lftとrgtの間にlftとrgtが収まっている部品は自分を構成する部品だとするやり方です。
ちゃんと説明できてないので、細かいことは次回にゆずるとして...
少人数では、
たしかに職場の環境ではイラネって感じのカラムですが、
大きなプロジェクトで使うとかになると、
セキュリティーやパフォーマンスを確保するために必要になります。
で、それがどうした?
これだけ眺めるのに10分もかかりませんでした。

でも、たとえば自分が学校出たてのエンジニア1年目で、
ふとしたことで、今回と同じようなことをして、
この技術を学んでいたと想定して、 

webサービス作るときに、パスワードにsaltとか付加してセキュリティを高めようとか、
そもそもパスワードの平文保存はダメとか、
部材表作成するときに、検索の時間がかかるようなら入れ子集合モデル使おうとか、 
そのまえに再帰的な部材表の作り方はやっかいだとか、

そういうことが提案できるってことなんですよね。
知っていたから、とかじゃなく
( ̄д ̄)「前もって知ってた技術だから、簡単に名前から辿りつけたのでは??」 

たしかに簡単に辿りつけたのはそうかもしれませんが、
時間かければ、行き着くことは可能だと思うんです。

今回のsaltやlft、rgtにしても、不可解な単語で、
この技術に至らなければ、なんとも納得できない存在なのですから。
やらなくても、出会うことくらいは...
いくつかオープンソースは読んだことありますし、
書籍買ったり、ブログ読んだりもしてますが、
知らない言語だから、使わないOSだからって距離をとらずに、
今回みたいに気になったら、
わかるとこだけでもちょっと出会ってみる、
ってことをすれば、多く学べるんだなと思いました( ー`дー´)キリッ 

ってことで、人生で初めて、Mac Book Pro買いましたっ( ー`дー´)キリッ

2012年1月16日月曜日

JavaScriptの連想配列でlengthを取得っ?!

JavaScriptでの連想配列と配列
あるブログに連想配列でlengthとれねーよ( `д´) ケッ!ってありました。
今回はJavaScriptでの連想配列と配列についてちょっと。

JavaScriptで連想配列を作成しようとすると、次のようになります。
var ary1 = {}
ary1['smile'] = ':-)'
一方配列はというと、
var ary2 = [];
ary2[0] = ':-)';
そっくりですねー(°Д°)。
でも上の例は一番混乱しやすい書き方をしています。 

ちょっとだけなのに、大きい違い。
ここの大きな違いって、 最初のカッコっこのところなんですね。
 {}と[] 
じつはこのカッコの違いで、生成してるものが違ってくるんです。

上の例をわかりやすく書きなおすと、 次のようになります。
var ary1 = new Object();
ary1['smile'] = ':-)'


var ary2 = new Array();
ary2[0] = ':-)';
つまり、どちらもオブジェクトを生成していて、
その生成しているオブジェクトが違っていたということなんです。
ArrayとObjectはどう違うか。
Arrayオブジェクトは配列用のオブジェクトで、 配列用のlengthも備えています。
一方、Objectはただ連想配列っぽく使える、
空のオブジェクト(prototypeをのぞいて)です。 もっとわかりやすく書けば、
var ary1 = new Object();
ary1.smile = ':-)'
console.log(ary1['smile']);
という感じになりますね。
連想配列は、オブジェクトを生成して、
そのプロパティに値を設定していただけなんです。
つまり連想配列でlengthがとれないのは...
配列は配列用のオブジェクトとしてつくられているので、
lengthがとれて、 連想配列はそれっぽく使えるオブジェクトを、
 連想配列っぽく使ってるだけなので、lengthはとれないってことがわかると思います。
おまけ。consoleの紹介





こんな風に書いてみて、 Google Chromeで開いて、真っ白な画面上で右クリック、 『要素の検証』を選択するとウィンドウが開きます。 そこの『console』タブを開いてみると、 console.dirに設定したオブジェクトをツリー上に展開してみれますので、試してみて下さい。

2012年1月10日火曜日

IEが嫌いな理由〜DOM level2の独自仕様...orz〜

おぅふ、IEで動かない
そういうことが何度あっただろうか。
そんな経験を積み重ねいつしかIE嫌いになってました。
DOM level2の仕様で
IEがなぜか独自仕様を展開し、
XMLやHTMLを操作するためのAPIのDOMのlevel2で、
他のブラウザと違っていることがそもそもの原因。
たとえば、
addEventListnerではなく、IEではattachEvent
こんなメジャーなとこですら違ってる。
対処方法として
javascriptファイルの先頭に、
↓↓こんな感じのをしこんで、おくっていうのはどうでしょうか。

var setFloat = ( "styleFloat" in document.getElementsByTagName("body")[0].style ?
               function(element, value) {
                   element.style.styleFloat = value;
               } :
               function(element, value) {
                   element.style.cssFloat = value;
               });
var addEvent = (window.addEventListener ?
               function(element, type, func) {
                   element.addEventListener(type, func, false);
               } :
               function(element, type, func) {
                   element.attachEvent('on' + type, func);
               });
addEvent(window, "load",initializeSelect )
イベントの追加と、cssのfloatの設定について。

2012年1月1日日曜日

あけましておめでとう!〜心機一転、fedoraを新しく〜

心機一転、OSを新しく
年も明けたということで、以前からアップグレードを怠けていたfedoraを新しくしました。
ご存知のとおり半年に一回くらいのペースでバージョンが上がっていくLinuxです。

USBからインストール
fedoraは簡単にUSBからインストールできるので、
以前と同様にUSBからインストールしました。
やり方は簡単!
(1)LiveUSB Creatorを使って、USBから起動できるfedoraを作成
(2)USBからfedoraを起動
(3)fedoraをインストールするアイコンがあるので、それを押下
(4)手順に従って、fedoraをインストール。

LiveUSB Creatorを使って、USBから起動できるfedoraを作成
とりあえず、LiveUSB Creatorをどっかのパソにインストールします。

そのあと、fedoraのisoをダウンロードします。
isoは「http://fedoraproject.org/」からダウンロード。

LiveUSB Creatorを起動して、「USE Existing Live CD」にダウンロードしたisoを指定します。
あとは、「CREATE Live USB」ボタンを押せばOK。

※isoをダウンロードしなくても、LiveUSB Creatorで、
作成するOSを指定するだけで作成できる機能があるっぽいので、最初それでやっていたのですが、
やたらと時間がかかった(1時間かかって10%完了)ので、途中でisoをダウンロードする方法に切り替えました。

USBからfedoraを起動
あとは簡単。
USBを差して、パソを起動するだけ。

※注意するのはUSBから起動できるようにBIOSで設定しなければならないこと。
またUSBから起動できないパソもあるので注意です。
そのへんはBIOS画面でちょっといじくって設定しました。

fedoraをインストールするアイコンがあるので、それを押下
USBからfedoraが起動できると、
パソにfedoraをインストールしてない状態でも、ふつうにfedoraがつかえます。

さて、パソにインストールするためには、
fedora16の場合、
まず左上の『Activities』を押下します。

でっかいアイコンが左端にいくつかならんできるので、
その一番下のHDDにチェックが入ったようなアイコンを押下します。

それで、fedora16のインストール画面が開きます。

手順に従って、fedoraをインストール。
あとはふつうに手順にしたがって、fedoraをインストールしていけばいいだけです。

思うこと
お手軽にできるので、USBからfedoraを起動して、
そこからfedoraをインストールしました。

じつはUSBからfedoraを起動した時点で、
パソに入ってるファイルとか見れるんですよね。
やはりちゃんとセキュリティ考えるならHDDにパスワード設定とか必要と実感。

たとえばこのUSBを他人のパソにつないで、電源いれて、
BIOSでUSB起動をできるように設定したら、
USBから起動したOSで、パソの中のファイル見れます。

いくらインストールしてるwindowsとかにパスワード設定してても、
そのwindowsが起動する前なので無効ですしね。