「グローバル変数」を含む日記 RSS

はてなキーワード: グローバル変数とは

2011-09-27

モノ指向

おれCで仕事してるけど、よく、

なんかグローバル変数ローカル変数の中間ぐらいの変数みたいなのあったらいいなー、

あと、そういう変数関数ポインタみたいなのがセットになってたりしたらなー、

などと思うよ。

いやもちろんオブジェクト指向知ってて思うんだけど。

でも、構造プログラミングやってて、オブジェクト指向言語って便利そーだなー、って、自然に思うもんじゃないのか。

思わないのかみんな。

http://d.hatena.ne.jp/ryoasai/20110926/1317044975

2011-06-27

jQuery.fileTree と 日本語ファイル名 (IIS & PHP)

IIS+PHP(つまりWindows環境)で

A Beautiful Site (http://abeautifulsite.net/)さんの

jquery.fileTreeを利用させてもらった。

以下、留意点...



script:

パスを指定しないと、もとのhtmlがあるパス(ディレクトリ)にあるもの解釈する。

(/jqueryFileTree.php と指定すると、公開しているルートディレクトリにあるjqueryFileTree.phpを探しにいく)

http://...と指定して他のサーバへ問い合わせるのも可能な模様(だが、試していない)。



root:

Windows場合は、最後に/または¥が必要。

d:/

d:/temp/

など



日本語文字化け対策:

hemlentries -> htmlspecialchars は必須。

 http://treatment-head.blogspot.com/2008/11/jquery-file-tree_21.html

 ただし、UTF-8EUC-JPでページを記述している場合は、さらに処理が必要。



phpではscandirなどのファイル処理において

windowsでは、mbstringの設定にかかわらず、引数SJIS渡し、戻り値SJIS返しの模様。

したがってUTF-8EUC-JPでページを記述している場合は、

その点を考慮してconnectorsフォルダにあるjqueryFileTree.phpを書き換える必要がある。

(きれいなソースでないので公開はちょっと控えます)


このphpファイルの先頭に

$_POST['dir'] = urldecode($_POST['dir']);

という行があるが(スーパーグローバル変数デコード済みで、さらにデコードするのは危険phpマニュアルに記載されている)

どのみちUnicode文字列URLデコードはこの関数では無理なようなので、phpマニュアルのUserNoteから拝借。

http://php.net/manual/en/function.urldecode.php



こちらにズバリが掲載されているか...と試してみたが、どうも動作がうまくいかなかった

http://ameblo.jp/pushurinko/entry-10287161493.html



他、ご参考

 http://life-hack.jp/blog/charly/151

2011-01-23

http://anond.hatelabo.jp/20110123010035

失礼 スコープグローバルはないので、グローバル変数というのは、語弊があるな。寿命が恒久の意味

お詫びのコード

template<typename T>

T * getT(){

 static T globalMem;

 return &globalMem;

}

さて・・・これって、グローバルなのかね?

ヘッダでテンプレート展開できる部分に置こうとすると、こうならねーか?グローバルな変数って。

狙ってこう使うのはいいと思うけど、あやまって、何でもかんでもstatic付けるとバグるよねぇ

//突っ込まれるかと思って、待ってたけど、やっぱり、そっちを突っ込んだかぁ・・・

//どう考えても、いみわかって突っ込んでるよねぇ、イヤラシイwww

//わかってんだから、いーじゃねーかw 揚げ足取りはwww

>いえ こう書くんですよ < なるほど 参考になった!ありがとう  ※ 寝るんで、御礼の言葉を先にかいておく。

http://anond.hatelabo.jp/20110123002943

関数の中に static って書くとグローバル変数になるプログラミング言語を知らないので

ぜひその言語を教えてください

いでグローバル変数定義を述べてください

http://anond.hatelabo.jp/20110123002036

あー 関数の中に static 変数名 って書くとグローバル変数になるって 知らないで 書いていてバグした人を知っている。

見つけたときにキレそうになった。

ポジションにもよるけど、直せるんだったら、直しとけば。で、報告すれば。ついでに直しておきましたって。

いいお客さんなら、次の仕事の単価がコッソリ、よくなる。おおっぴらにはしないけど、根切りの時の圧力が弱い。

悪い客なら、ラッキーで次もガンガン値切ってくる。

 

前者なら、今後も、よくやってあげればいいし 後者なら、次のいいお客さんを捜すまで 様子を見て言われたらなおぜばいい。

とある大規模インフラの基幹システムなんだけど、納品して以来、誰にも原因が分からない不具合が続いていたのでした。よく品質保証部を通ったなと不思議に思ってるんですがね。

現地で動かしてみないと分からない、って奴かな?

所詮は外注が格安で作ったシステムからこんなもんなんだろう。しかし、数年もほったらかしにしておく神経がよく分からない。

で、今回、そのシステムの改修で俺が担当プログラマーになったわけだが、組み合わせ試験をしていると、出るんだわ、この現象が。現象を見ていて再現条件を想像。結果、ある条件をそろえると100%再現。復旧させるには、リブートさせるか、ある条件を1秒以内に整えれば復旧する。

なんで「誰にも分からない」のかよく分からない。見てて動作が変だったから、LANアナライザ突っ込んでハンドシェーク見てたら仕様書通りになってねーでやんの。試験したのか?これ。

そこからスタートして、2つのシステムを行ったり来たりしながら逆に遡る事8時間。原因発見

さて、問題は、今回の受注範囲に関係無いんだよな、これ。直すべきか、ほっとくべきか。

でもなー、プログラムがなー、糞すぎるんだよなー。直したくねぇ。

何しろ、ループ変数のiがグローバル変数になっているプログラムなんだもの。どこのキ印だ。

2010-08-10

システム統合してはいけない

「次期システムでは、今まで6つに分かれていたシステムが1つに統合されます」

今思えば、この台詞が出た時点で引き返すべきだったんだと思う。

気付けば「初期値が NULL のテーブル」の隣に「基本が NOT NULL のテーブル」が鎮座していた。

システムから引き継がれた COBOL の遺産が、システムを跨いで好き勝手DB アクセスしていた。

今まで疎結合を保っていたシステムが、DB という名前グローバル変数を介して密結合となった

DAO みたいな生易しい思想なんて無い、全てのプログラムDB への自由なアクセスを許された世界

既に DB の内容を保証してくれるモジュールは無くなった。誰も一貫性保証してなどいない。

当然バグも頻発する。バグ票の起票数は 3000 を超えた。全部 EXCEL 管理なのが憎さに拍車をかけている。

今日、初めて人が壊れた。とりあえずバグ票を起票する。

うそろそろ駄目だと思うけど、誰も「やめよう」なんて言ってくれないのが一番辛い。

2009-08-07

優秀なプログラマたまに起こる逆行(退行)現象

あれは私がまだ大学助手をしていたころだから3年ほど前のことだと思う。

私の勤めていた大学(情報系)では「プログラミング研究会」みたいなサークル活動が行われていて

プログラミング講義を受け持っていた私はそのサークルにちょくちょく顔を見せるようになっていた。

そこにはとびっきりかわいい女子学生が一人いたのだけれど、その子はゲームが大好きで

自分でもゲームが作りたい」と一念発起してゲームコンテスト作品を出品することになった。

しかし、彼女プログラミング講義(Java)を1年くらい受けているものの、

本格的なモノを作った経験がなく、ひとりでは行き詰まりをみせているようだった。

彼女はひとりでいることが多く、パソコンに向かって黙々とプログラムを書いているのをよく見かけた。

それを気にかけていた私はたま彼女ランチに誘うようになり、彼女の方もしだいに私に打ち解けてきた。

私たちはだんだんと仲良くなっていった。私は彼女キュート笑顔に魅了されていった。

ある日、彼女が私のもとにやってきて、もじもじと顔を赤らめながら上目づかいにこう言った。

先生、頼みごとがあるんですけど・・・」

「なんだい?」

メッセンジャーアドレス教えてくださいませんか?」

これから恋の話が始まるのを期待したあなたは別のページを読んだ方がいいかもしれない。

これから始まるのはプログラミングの話だ。

その日から毎日のように彼女は私にメッセンジャープログラミングの相談を投げかけてきた。

私と彼女は連日のようにプログラミングについて語り合った。

彼女は大変優秀で、私の教えるプログラミングテクニックをみるみる吸収していった。

私は彼女才能に驚き、彼女が将来優秀なプログラマになるであろうことを確信した。

しかし、ときおり彼女が優秀であるがゆえの面白い逆行現象が起こったのだった。

ケース1

ある日、私は彼女メモリ意識してプログラミングをしていないことに気づいた。

Java ではメモリ意識する場面というのは少ないが、まったく無いわけではない。

私は彼女プログラムメモリ無駄に使っているということを指摘した。

しかし、よく聞いてみると、彼女メモリハードディスクくらいの感覚しか持っていないことがわかった。

驚かないでほしい。

私の経験上、情報学部の学生の半分以上がメモリハードディスクの区別がついていない。

それを知っている私は落胆することもなく、落ち着いて彼女メモリの説明をすることができた。

彼女は私の説明を聞き「よくわかりました」と、とびきりキュート笑顔を見せた。

しかし、翌日、彼女の書いたコードを見てがく然とした。コードが次のように変更されていたのである。

	for (int i = 0; i < MAXHOGE; i++) {
		doSomething(i);
	}
	for (int i = 0; i < MAXFUGA; i++) {
		doSomething2(i);
	}

	int i;
	for (i = 0; i < MAXHOGE; i++) {
		doSomething(i);
	}
	for (i = 0; i < MAXFUGA; i++) {
		doSomething2(i);
	}

彼女はこのコードを私に見せながら、相変わらずのキュート笑顔でこう言った。

「このほうが使うメモリが少ないですよね!」

ケース2

ゲームコンテストの締め切りが近くなってきて、実際彼女はよく頑張っていたのだが、

どうしても間に合いそうになかったので、私もコード書きを手伝うことになった。

とある部分を書いていたとき、重複したコードを見つけたので Template Method パターンを使って書き直した。

Template Method パターンというのが何かというと、同じことをするコードがいくつもの場所でばらばらに書かれないように

一つのクラスにだけ書いて、それを継承して使いまわすという手法(デザインパターンの一つ)だ。

私はこの手法を彼女に教えようとは思わなかった。

なぜなら、彼女継承だとか委譲だとかポリモーフィズムとかがよくわかってないのだ。

驚かないでほしい。

私の経験上、情報学部の学生の99%が、その、ポリホーなんとかが分かってない。

私は彼女には何も言わずにこっそりコードコミットした。

しかし、彼女はそれに気づいていた。

翌日から彼女コードの書き方ががらりと変わった。

彼女はいたるところで継承を使うようになっていたのだ。

彼女は私のコード自分で解析し、新たなる発見を独力でしていた。

重複したコードがあればそれを徹底して継承で解決しようとしている。

そう、差分プログラミングだ。

差分プログラミングの正式な定義は知らないが、彼女は IS-A 関係のない継承を使ってしらみつぶしに

重複コードを書き直していた。

そのコードを見せながら、天使のような笑顔彼女はこう言った。

「こうするとコードの量が減りますよね!」

まとめ

私がこの文章で言いたいことは、知の高速道路を渡ってきた若い優秀なプログラマ

ときおり妙な退行現象を起こすということだ。

それは普通の道を通ってきた古い世代にとっては実にみょうちきりんなことに思えるかもしれない。

しかし、それは彼らなりに理由があってのことであり、馬鹿だからやってるわけではない。

彼らは優秀であるがゆえにそういったことを起こすのだ。

そして彼らは優秀であるがゆえに、自分が間違っていることを理解するのも速い。

もし、あなたのまわりで若いプログラマが逆行現象を起こすのに遭遇したとしても、

どうか暖かく見守ってほしい。

ちなみに

上で紹介した2件に関しては、彼女にはそのあと説明をして理解を得ることができた。

彼女は本当に優秀なプログラマだ。

しかし我々はそれで油断してはならない。

いつか彼女はその可愛らしい顔をにっこりとほほ笑ませながらこう言うかもしれないのだ。

ローカル変数よりグローバル変数のほうが便利ですよね!」

2009-05-21

http://anond.hatelabo.jp/20090519185138

一時変数数学風に短くする流儀もあるから、それに比べれば省略なんてマシな方だろ。

グローバル変数についちゃ省略する流儀は廃れてる。

2008-12-30

http://anond.hatelabo.jp/20081230161445

継承とかしないなら構造体で良いような気もする。

自分はメンバ変数はm_つけてグローバル変数はg_つけるようにしてる。

2008-11-17

http://anond.hatelabo.jp/20081117191821

自分のイメージ二股か。

基本的には、終了条件があって、

  • ○○なら××をする(返す)
  • そうでなければ、△△のために関数(実は自分自身)を呼び出す

になると思うんだよね。

それともう一つ重要なのがデータ構造と、変化する変数

この二つから、反復しながら、何が変わってるのか、どう対象範囲が変化してるか、が分かれば、大まかなところはつかめるんじゃないだろうか。

あと、デバッガ使うと分かりやすいんじゃないだろうか。


書くほうは、似た処理を関数化したら再帰だった、だろう。

2008-10-27

Java屋らしい』とは?

中途半端に優秀なプログラマが「正しいプログラミングテクニック」だと妄信しがちな3つポイント

http://d.hatena.ne.jp/fromdusktildawn/20081026/p1

ちょっと囓っただけの素人が自分を過信して陥る三つの罠?

http://d.hatena.ne.jp/JavaBlack/20081026/p1

d:id:fromdusktildawn:20081026さんは「共通化とか抽象化ができるようになった中途半端に優秀な』人を対象にしているのに対して、d:id:JavaBlack:20081026さんは『ちょっと齧っただけの素人』を対象(元記事に対してかもしれない)にしているので、適用対象レベルがそれぞれ違う気もするけど。

d:id:JavaBlack:20081026さんの記事に対するブクマコメントの幾つかやトラックバック先において、『Java屋らしい』との書き込みがあるけれど、具体的に『Java屋らしい』とはどんなことを指すのでしょう?

当方嫌われ者エンタープライズ開発withJavaな人間ですが、Javaがよく使われるエンタープライズ向け開発などを行っていると、プログラミング企業入ってから覚えました、っていう人の方がマジョリティだから、こういう“プログラミングセオリー”のようなものは知る機会がないと言っていい。よほどいい先輩に当たらないと、こういうことすら教えてくれないことの方が多い。

プログラマなら自分で調べて当然、という意見もあるだろうけど、上記“マジョリティ”の彼らは、自宅でコーディングなんてするはずがないし、早くコーディングなんて卒業したい、と考えている人種

そんな人たちは、こういうことを『知らない』し、『知ろう』とも思っていない。

そういう現場にとっては、

とある程度型にはめて指導することは、とりあえず『最低限のレベル』を守るためには有効だと思うのだけれど。まぁ元記事では『中途半端に優秀な』とわざわざ断っているから、こういうことを最低限知っていて、杓子定規になんでもかんでも共通化したりローカル変数ばっかり使っている人に対しての進言なんだろうとは思いますが。

Java屋らしい』とは、Javaが静的型付け言語だけに、なんでもかんでも「こうしなければいけない、ならない」と断定してしまう点を指して『堅い(硬い?)』ことを言っているのでしょうか?

あと、『Java屋は長ーいメソッド名が見やすいと感じるらしい』というコメントについては、Java屋がCOBOLerに対して、

  • IDENTIFICATION DIVISION.
  • ENVIRONMENT DIVISION.
  • DATA DIVISION.
  • PROCEDURE DIVISION.

なんて書くのは冗長だよなー。とか、xx区分みたいな項目が横並びに何十項目もあるRDBなんて作るんじゃねぇ、とか思う心理と似たようなものなんでしょうか。

そもそもJavaがこんなにdisられるようになったそもそもの理由も知りたい。

教えてLLな人。

2008-10-09

COBOL経験者のCOBOL以外の言語でのプログラミング

COBOLにもローカル変数サブルーチン引数はあるんだけど、それを使っちゃいけない企業文化で育った結果、他の言語でもその慣習を押し通したコードを書き続ける人が多いみたい。要はCOBOL以外の言語勉強してないだけなんだけど。

業務経歴書にCOBOLって書いてあったら書類で不採用…ってしちゃった方が面接に使う時間を減らせて楽そうとも思うんだけど、「それ明らかに偏見理不尽だろ」って自分ツッコミが入っるのでそれはやってないんだよね。

でも実際問題今までにお会いした「COBOLから業界に入った人」はみんなこんな感じで、ウチでは採用できない確率100%なんだよなあ。求む!偏見を覆せるCOBOLer!なんつってな。普通にまともにプログラムが書ける人ならCOBOL歴の有無なんかどうでもいいです。むしろ業務経験の有無すらどうでもいい。

2008-10-07

今日。入社6ヶ月目の出来事

配属から4か月が経ち、担当する制御を移ることになった。

今の制御での最後の仕事は、先輩が作った2つの関数プログラムチェックリストの作成だった。

グローバル変数だらけで、何のための関数なのかも分らず、関数仕様書もない。

質問しに行くと仕様書を見せられて意味を説明されたが、具体的に何の値が入れば正しいかは分からなかった。

それでも自分なりに出来る限りリストを作り、提出の日になった。

リストを見た上司は言った。


「うーん‥‥‥そうか‥‥‥

‥‥‥ネタばらしをするとな、実はこの関数って、前にお前がチェック

をしたことがある関数とほとんど同じなんだよ。」


自席に戻り、今までにやったチェックリストとソースコードを漁る。

あった。

1件につき数十個の変数配列の値を確認しなければいけない巨大なリスト

実際は未実装やバグで件数の半分もまともに動作しなかったものだ。

確かに、その関数は今の関数とほとんど同じだった。

しかしチェック完了の日付は7月末 ‥‥ 右も左も分からない頃だ。

当然関数の内容なんて理解していないし、覚えてもいない。


「だから、先週お前に任せた時点で、『これ前にも見た関数だ』って気付いて、

その関数リストを基に作成して欲しかったんだよ。」


腹が痛くなった。

別のOJTの先輩は「その作らせ方には問題がありますよ」と言ってくれたが、

中途半端で移るのはよくない。」とのことで、結局自分が週末までに作ることになった。

制御の移動もリストの完成まで延期になった。


結局の所問題は何も解決していない。

元ネタが見つかったのは二つのうち一つ‥‥

その後の残業中に、腹痛が吐き気に変わってきたので8時過ぎに早退した。晩飯は無理っぽい‥


追記:

http://anond.hatelabo.jp/20080909191957

前回がたったひと月前なのに随分昔のようだ。

上司今日、俺の週報のことで部長に怒られていた。

OJTを全くせず、プログラム単体テストばかりさせているのがいけなかったらしい。

ただ俺のお向かいの席で怒るのはやめて欲しい‥‥丸聞こえでこっちまで惨めになる。

2008-07-13

就職してからいままでのことを書いてみる。

就職氷河期の真っ只中に入った会社従業員数一桁のソフトハウス

大学生のころバイトシミュレーターを作っていたり、趣味ゲームを組んでいた僕はすぐに採用になった。

事業内容はあまり気にしなかった。

プログラムを組めればなんでもよかった。


最初は社内でスタディという名の研修?をやった。

研修といっても、電話のとり方とかでなくプログラミング

簡単なプログラムを組んで、「ああ、簡単に仕事ってできるんだな」と思った。


数週間たったころ、あるプロジェクト会社の先輩と2人でアサインされた。

やったことのないUNIXプログラミングだった。会社にはUNIXはない。開発環境もない。

そして他の会社の人から仕様を聞いて、モノを作るのも初めてだった。


まだ僕が客先に行くことができないので、先輩が話を聞いてきて、いろいろな指示をする形で仕事が進んでいった。

だけど、仕様がわからない。

客にメールを投げて聞いても、客自体も協力会社なのでわからない。


あとでこの業界構造がわかったのだが

 発注元→元受→(ウチの会社にとっての)客→ウチの会社

というように、俗に言う孫受けというモノだった。


元受にメールを投げているうちに、ウチの会社の質問は記憶のかなたに消えていった。


確か、「仕様がわかるまでソースを読んで現状を把握しといて」というようなことを客に言われた気がする。

そしてソースを自社に持ち帰り、読んでいたのだが、もともとがどんなプログラムなのかもわからないため、非常に難航する。

なんといっても、main関数だけで数千行のソースもあるのだ。グローバル変数もたくさん使っている。


学生のころから読んでいた

C++基礎講座 http://www.amazon.co.jp/gp/product/4844313088/

C++実用講座 http://www.amazon.co.jp/gp/product/4844313096/

にも、main関数は短めに、グローバル変数も極力使わないように。と書いてあるのに。


そして、ソースの変更場所を客先に説明するため、変更点を全て列挙してソースWordに貼り付けて色をつけるのだ。

無駄な作業だった。

今考えるとsvn or vss or cvs使えばいいじゃない、って思う。


学生のころに想像していた仕事とぜんぜん違った。


まだいろいろ問題点があるけど、早い話がデスマーチのにおいがプンプンするプロジェクトだった。

2007-11-08

60行テンプレートエンジンがパワーアップしてレイアウト機能に対応

前の60行テンプレートエンジンを改良して、レイアウトテンプレート機能を追加してみた(それでも全部で90行)。


レイアウトテンプレート機能とは、例えば個別のテンプレートが<table>...</table>を出力して、それをレイアウトテンプレートが<html><body>...</body></html>で囲って出力するとかそんなの。

詳しくは終わりの方のサンプルをみてくれ。


これは Ruby on Rails(とその仲間たち)にある便利機能のひとつ。

ついでにいうとSmartyにはない機能のひとつ。

今まで知らなかった人はぜひ試してくれ。チョー便利だから。


前回はたくさんのブックマークありがと。

コメントで「男前テンプレート」と名前がついてたので、勝手採用

名前がキモいっていわれるよ?でもそんなのカンケイネー


あと、これ以上の機能追加はしないので、各自勝手に改造して使ってくれ(そのためにコメントをつけてるから)。何でも人任せにするな。


コード

<?php
/*
 *  OtokomaeTemplate.php -- レイアウトテンプレートに対応した90行のテンプレートエンジン
 *
 *  - レイアウトテンプレート中で echo $_content; とすると中身が表示される。
 *  - テンプレート中で設定した変数レイアウトテンプレートで使うことが可能。
 *  - レイアウトテンプレート名をテンプレート側で指定することも可能。
 *  - 使い方:
 *      require_once('OtokomaeTemplate.php');
 *      $TEMPLATE_DIR    = 'templates';  // 省略可、パーミッションに注意
 *      $LAYOUT_TEMPLATE = 'layout.php'; // 省略可
 *      $context = array('title'=>'Example',
 *                       'list'=>array(10,'<A&amp;B>',NULL));
 *      include_template('template.php', $context);
 *  - 要 PHP 5.1 or later
 *  - ライセンス: public domain (自由に改造してね)
 */

/*
 *  設定用のグローバル変数
 */
$TEMPLATE_DIR    = NULL;   /* テンプレートを探すディレクトリ */
$LAYOUT_TEMPLATE = NULL;   /* レイアウトテンプレートファイル名 */

/*
 *  テンプレートを読み込んで実行する。
 *  $_context は変数名をキー、値を要素とする連想配列。
 *  $_layout はレイアウトテンプレートファイル名。
 *  - NULL または省略した場合は $LAYOUT_TEMPLATE を使う。
 *  - FALSE ならレイアウトテンプレートを使わない。
 *  - $_context['_layout'] = '...'; とすればテンプレート側でも指定可能。
 */
function include_template($_filename, $_context, $_layout=NULL) {
    global $LAYOUT_TEMPLATE;
    $_content = render_template($_filename, $_context);
    if (@$_context['_layout'] !== NULL)   // テンプレート側で指定された場合は
        $_layout = $_context['_layout'];  // それを使う。
    elseif ($_layout === NULL)            // 引数で指定されなかった場合は
        $_layout = $LAYOUT_TEMPLATE;      // デフォルトファイル名を使う。
    if ($_layout) {
        $_context['_content'] = $_content;  // レイアウトテンプレート中で使う変数
        $_content = render_template($_layout, $_context);
    }
    echo $_content;   // or return $_content;
}

/*
 *  テンプレートを読み込んで実行し、その結果を文字列で返す。
 *  include_template() の実体。
 */
function render_template($_filename, &amp;$_context) {
    $_cachename = convert_template($_filename);
    extract($_context);     // 連想配列ローカル変数に展開
    ob_start();
    include($_cachename);   // テンプレートを読み込んで実行
    return ob_get_clean();
}

/*
 *  テンプレートファイルを読み込み、convert_string() で置換してから
 *  キャッシュファイルに書き込む。読み込み時のロックは省略。
 *  (file_get_contents() もファイルロックできるようにしてほしいなあ。)
 */
function convert_template($filename) {
    global $TEMPLATE_DIR;
    if (! file_exists($filename) &amp;&amp; $TEMPLATE_DIR)
        $filename = "$TEMPLATE_DIR/$filename";
    $cachename = $filename . '.cache';
    if (! file_exists($cachename) || filemtime($cachename) < filemtime($filename)) {
        $s = file_get_contents($filename);
        $s = convert_string($s);
        file_put_contents($cachename, $s, LOCK_EX); // LOCK_EX サポートは 5.1.0 から
    }
    return $cachename;
}

/*
 *  テンプレートの中身を置換する。
 *  - '#{...}' を 'echo ...;' に置換
 *  - '%{...}' を 'echo htmlspecialchars(...);' に置換
 *  - ついでにXML宣言も置換
 */
function convert_string($s) {
    $s = preg_replace('/^<\?xml/', '<<?php ?>?xml', $s);
    $s = preg_replace('/#\{(.*?)\}/', '<?php echo $1; ?>', $s);
    $s = preg_replace('/%\{(.*?)\}/', '<?php echo htmlspecialchars($1); ?>', $s);
    return $s;
}
?>

サンプルPHPコード:

<?php
require_once('OtokomaeTemplate.php');
$TEMPLATE_DIR    = 'templates';
$LAYOUT_TEMPLATE = 'layout.php';
$context = array('list'=>array(10,'<A&amp;B>',NULL));
include_template('template.php', $context);
?>

レイアウトテンプレート(layout.php):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <body>
    <h1>%{$title}</h1>
    <div id="maincontent">
<!-- テンプレートの内容 -->
<?php echo $_content; ?>
<!-- /テンプレートの内容 -->
    </div>
  </body>
</html>

テンプレート(template.php):

<?php // レイアウトテンプレート名をテンプレート中で指定する場合 ?>
<?php //$_context['_layout'] = 'mylayout.php'; ?>
<?php // レイアウトで使用する変数テンプレート中で指定する場合 ?>
<?php $_context['title'] = 'レイアウトのサンプル'; ?>
<table>
<?php foreach ($list as $i=>$item): ?>
  <tr bgcolor="#{$i % 2 ? '#FFCCCC' : '#CCCCFF'}">
    <td&gt;#{$i}</td&gt;
    <td&gt;%{$item}</td&gt;
  </tr>
<?php endforeach ?>
</table>

出力例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <body>
    <h1>レイアウトのサンプル</h1>
    <div id="maincontent">
<!-- テンプレートの内容 -->
<table>
  <tr bgcolor="#CCCCFF">
    <td&gt;0</td&gt;
    <td&gt;10</td&gt;
  </tr>
  <tr bgcolor="#FFCCCC">
    <td&gt;1</td&gt;
    <td&gt;&lt;A&amp;B&gt;</td&gt;
  </tr>
  <tr bgcolor="#CCCCFF">
    <td&gt;2</td&gt;
    <td&gt;</td&gt;
  </tr>
</table>
<!-- /テンプレートの内容 -->
    </div>
  </body>
</html>

いくつか補足:

2007-11-01

PerlClass::Data::Inheritableの解析

唐突にClass::Data::Inheritableのソースコードについて説明してやんよ。

使い方とかの説明はこの辺でも読んでから出直して来い、ごるぁ!

まぁとりあえずソース見てみろ、下記にはっつけてやっからよぉ!


 1: package Class::Data::Inheritable;
 2:
 3: use strict qw(vars subs);
 4: use vars qw($VERSION);
 6: $VERSION = '0.06';
 7: 
 8: sub mk_classdata {
 9:     my ($declaredclass, $attribute, $data) = @_;
10: 
11:     if( ref $declaredclass ) {
12:         require Carp;
13:         Carp::croak("mk_classdata() is a class method, not an object method");
14:     }
15: 
16:     my $accessor = sub {
17:         my $wantclass = ref($_[0]) || $_[0];
18: 
19:         return $wantclass->mk_classdata($attribute)->(@_)
20:           if @_>1 &amp;&amp; $wantclass ne $declaredclass;
21: 
22:         $data = $_[1] if @_>1;
23:         return $data;
24:     };
25: 
26:     my $alias = "_${attribute}_accessor";
27:     *{$declaredclass.'::'.$attribute} = $accessor;
28:     *{$declaredclass.'::'.$alias}     = $accessor;
29: }
30: 
31: 1;

短いソースだなーこれ。でもな、なめんじゃねーぞ。短いけど色々な技術が盛り込まれてんだよコレはよぉ。


ハイ、まず3行目。

かるくstrictについて説明してやんよ。心して聞けよオマエラ。

strictっつーのはだな、つまりPerlにおける曖昧な部分をすこーしだけチェックしてくれるスグレモノなんだなコレが。

とりあえずざっくり言うと三つの機能があってだな、下記のよーに書くわけだ。


 use strict 'vars';
 use strict 'subs';
 use strict 'refs';

varsってーのは簡単に言うとmyとかourとか宣言しろボケってやつですわ。

subsは裸体は許さんってやつですの、$とか%とかついていない裸の文字列をエラーにしてくれんだよ。

refsってのが一番やっかいな代物でな、これはムツカシイ言葉で言うとシンボリックリファレンスってんだが、要は変数名に変数を使うとエラーにしてくれるってこったよ。

で、これら全部ひっくるめてuse strict;なんだな。わかったか?オラ!

ちゅーことはだ、3行目を見ると意図的にrefsだけ外してるのがわかるよな。

つまりコレはこのコードのどこかで変数名に変数を使うってことを明示していることにもなるわけだ。けけけ。

あーもういいもういい、次だ、次。

4,5行目を見てみろよ。今時our使わずにuse vars使うなんてどんだけー

ははは、まぁまてよ。

ourってのは明示的にグローバル変数を定義するもんなんだが、このourってやつが導入されたのがPerl5.6からなんだよ。

Perl5.5のころはourなんてなかったからグローバル変数定義すんのにこのuse varsを使っていたわけだ。

つまりこのモジュールはPerl5.5環境でも動くように配慮しているわけなんだな、ちゃんちゃん。ほほほ。

あーもう全然すすまねーよ。チクショウ、が、ま・・・・。

で、11-14行目。これはref関数使って$declaredclassがオブジェクトだったら死ぬって処理だ。

require CarpっつーのはCarpモジュールを動的にロードしてるっていうことだよぅ。

で、Carp::croak関数使ってエラー文はいて死ぬ、と。ちなみにこのCarp::croakってはまぁdie関数みたいなもんなんだ。

違いとしてはエラーの発生した原因を呼び出し元の奴のせいにして自分は悪くないんだよってアピールすることかな。まぁ実際使ってみりゃわかるよ。

さぁ、16行目。本編突入だ。長かった。長い道のりだったなお前ら。

sub {}ってのは無名サブルーチン(関数リファレンス)ってやつだ。で、ここで注目すべき点はただひとつ!!!!!

19-23行目あたりをぼーっとみてると$declaredclass, $attribute, $dataっていう変数を使用していることがわかる。

これらの変数は9行目で受け取ったmk_classdataへの引数だ。

ここで問題が発生する。

ダダダダン!ダダダダン!ここで問題が発生する!

myで宣言された変数賞味期限スコープの終端だ。それはわかるな?

つまり9行目で宣言された$declaredclass, $attribute, $dataといった変数どもは29行目のスコープの終端で消滅してしまうわけだ。

しかし!その消えてしまうはずの変数どもをsub {}という無名サブルーチンの中で使用してしまっている!!!

これが世間一般に語られているクロージャという仕組みなのだ!!!!!!うはははははははh!!!

本来生涯をまっとうするはずだった変数たちが別のサブルーチンの中にまぎれてしまうとその別のサブルーチンが消えてなくなるまでは死ぬことを許されなくなるのである!!!ざ・不☆老☆不☆死!

なんたる奇妙奇天烈なことであるが、この現実を受け入れることによってお前らの道が開けるんだ!!!すげーだろぉがよぉ!!

ボクはッ、キミがッ、クロージャを受け入れるまでッ、殴るのをやめないッ!


さて、肝心の16-24行目のアクセサ部分の処理の解説だけども、

引数が渡されてなければ特になんの処理もせずに$dataを返している。$dataってのは死ぬことを許されなくなったカワイソウな変数君だ。

つまり、Class::Data::Inheritableってやつはアクセサに渡された値をどこで保存してるのかというと、紛れも無いこの$data君に他ならない。

$data君がニート君になっちゃうとたちまちデータの読み書きができなくなるのであまり働かせ過ぎないように注意しよーね!

ハイ、次はアクセサに引数が渡された時の処理だけどな、20行目を見てみろ。$declaredclassに格納されてる値はmk_classdataメソッドを使用したときに格納された値になる。


 package Hoge;
 use base qw/Class::Data::Inheritable/;
 Hoge->mk_classdata('hoge_accessor');

つまり上記の処理で例えると、$declaredclassには'Hoge'という文字列が入ってることになんだな。

で、この'Hoge'と$wantclassに入ってる値を比較しているわけだが、


 package Hoge;
 use base qw/Class::Data::Inheritable/;
 Hoge->mk_classdata('hoge_accessor');
 
 Hoge->hoge_accessor('aaa');

上記の処理で例えると$wantclassには$declaredclassと同じく'Hoge'が入ってくることになんだな。うっひょー。

んで、20行目のif文は$wantclassと$declaredclasが違う場合にだけ19行目の処理を実行しているわけだからこの場合はスルーするわけだぁ。ひょひょひょ。

じゃあだな、$wantclassと$declaredclasが違う場合ってどんな場合?ってことだが、下記に例を示すから目ん玉引ん剥いて網膜から直接見てみろよこのボケ野郎どもが。


 package Hoge;
 use base qw/Class::Data::Inheritable/;
 Hoge->mk_classdata('hoge_accessor');
 
 package Foo;
 use base qw/Hoge/;
 
 Foo->hoge_accessor('bbb');

HA!HA!HA!こういう場合だよ米ベー。$wantclass=Fooで$declaredclas=Hogeになるんで19行を実行し、Fooをベースにしてmk_classdataを呼ぶことでFooに同じ名前の新たなアクセサを提供し、元クラスHogeの値を壊さないようにするわけですなぁ。

考えた人すごいですなぁ。これがClass::Data::Inheritableが継承可能なクラス変数といわれる由縁でするまする。

で、最後の26-28行目はコレらの便利な処理をしてくれる$accessorさんをクラスに登録するというわけですよぉ。

27,28行目の*ってのは型グロブ変数ってという奴で、型グロブに対して無名サブルーチンを突っ込むと動的に関数を定義できるんだなぁコレが。

でここで、初めに俺が語った話を覚えてるか?へっ、オマエラなら覚えてないだろうなけっけ。use strictの話だよ。refsだよrefs。

ここでrefsを省いていたのが利いて来るんだ。refsって何だった?ホラ言ってミソ?

うんうん。変数名に変数を使えないようにするだったね。

で良く見てみると型グロブ変数に対して「$declaredclass.'::'.$attribute」っていう変数を使おうとしているよね?これをしたかったからrefsだけ仲間外れにしてたわけですね。

はは。

あー、あー、あー。

これで終わりだよぅ。みんなわかったかな!?

コレ読んでもわからんやつはもう死ぬか、もしくはわからん用語について死ぬほど調べてもっかい読みなおしてみろこのド低のぅッ・・・ごふんごふん、このクサレ脳みそがぁ!!!!!!!!!!!!11



プログラ増田のあなぐら

2007-04-23

スパゲティコード

$input = 3;
include("next.php");
if($Result){
 print "成功";
}
exit;

PHPソース見てたら、こんなコードが出てきて憤死しそうになった。

文中で関数を呼ぶようにincludeされている事も衝撃だが、何よりそのinclude先とグローバル変数で通信していると言うすさまじさ。

当然、一定の条件でnext.phpは別のPHPファイルをincludeしている。

こんな見事なスパゲティコードはじめてみた。家に帰りたい。

2007-04-12

俺記法感想

増田職業プログラマっぽいのが、結構な割合で居そうなのが判った。

そして自分も楽しめた。ありがとう

こういう話大好き。


こうやってみんなスタイル見ると、どのスタイルも大して見づらい事もないんだよね。

でも実際の引継ぎ仕事やら、全面改修やらで回ってくるソースって、ありえない事になっちゃってる率があまりに高いよね。

ああいう、訳の判らない事態に陥る原因とかがやんわり判ったりすると、ちょっと面白いのかもなぁって思った。


例として、過去に自分が死にかけた(と言うかぶちきれて、仕事放り投げたくなった)ソース

・一般のパソコン向けパッケージソフト(C言語ベース

関数が10個程度しかない

関数一つ当たりの行数が1万越え

・内switch文が占める割合9割

おまえはBASICか(いや、basicでももっとましだけど)と突っ込みたくなった。

用はswitch文一つ一つが関数の役割を果たしてて、それをグローバル変数一つで切り替えて制御していると言う…言っててむなしくなってきた。

- 転職ならen
- 派遣ならen
 
1ページ中1ページ目を表示(合計:20件)