はてなキーワード: Perlとは
http://anond.hatelabo.jp/20070924220240
最初の頃は単なる知識を得る作業だから仕方ない。つまらないが、最初に知識をかき集めるその方法が一番効率がいいから、テキストはそういう構成になっている。面白いのは、手元に材料が一通り揃ってから、「この課題を解決せよ、手段は問わない」という類の問題が出される段階になった時。
2chのプログラミング板の宿題スレに一時期住んでたんだけど、一番面白いと思った課題は「迷路を解くプログラムを作れ。実装方法はいっさい問わない。速いプログラムほど良いとする」というもの。「迷路は壁=1、通路=0みたいなテキストデータで与えられ、入り口と出口は壁に隣接…」みたいな仕様だけは与えられたが、それ以外何もなし。
解決方法を考えるのは楽しいし、自分にできない事をやってくれるプログラムというのはコンピュータが自分で考えているみたいで妙に愛着が湧く。
プログラムにやらせたい作業が見つからない、というのは多分想像力の欠如でもなんでもなく誰もが通る道。実際、日常生活でそんな機会はなかなか無い。
自分の場合、Perlでwebサイト関連ツールを作るところから始めたかな。フォームに入力した内容が追加されていくだけの簡単な日記帳とか、後はカウンターとか、そんなものをチマチマ作る事から始めた。ほとんどはもう使ってないが、タブ区切りテキストデータをhtmlのtableに直すスクリプトは地味に今でもしょっちゅう使う。
2chのdatを読み込ませて書き込み数の遷移を出すプログラム(http://www.tv2ch.info/?3 みたいなの)も、時間辺りの書き込み数データをテキストで書き出すところまで作ったな(Excelにコピペしてグラフツールを使えばこのサイトのようなグラフが書ける所まで)。テキスト周りの処理が出来るならば簡単に書ける。
あとは、Ragnarok Onlineで時間辺りダメージを最大にするためにはどのようにステータスを成長させれば良いかの算出をプログラムにやらせたりもした。あり得るステ振り全てに対し総当り探索。(分かる人だけに注釈を入れると職業はハンターで、算出値は鷹ダメージ込み。敵のdefに応じてダメージが変わってくるんで複数パターン出した)
ネトゲだと、某ゲームでアイテムの相場を入力すると、儲かりそうな生産レシピを出力してくれるプログラムも書いた。書いたが、打ち込むべきデータを集めるのが面倒すぎて使用は断念した。
総当りで思い出したが、HTMLで色見本を書き出すプログラムも書いた。http://www.tohoho-web.com/wwwcolor.htm の216色見本みたいなのをプログラムで生成させた。
教科書でやった課題は、ソートプログラムくらいかな。アルゴリズムの流れだけ理解したら、教科書を閉じてそのアルゴリズムを自力で実装する。写経は面倒でやれなかった。
http://anond.hatelabo.jp/20070924224733
普段使ってみて便利だなとか思うソフトウェアはないの?
普段よく使うソフトは……まぁタブブラウザとかFLVプレイヤーとかTerapad辺り? それこそメモ帳を作る、とかならネットにソースがありそうなきもするけれど……
http://anond.hatelabo.jp/20070924225135
俺の場合は、昔からやってたサイトがあったから日記とかの管理が面倒だったんでフリーのperlのスクリプト弄ったりPHP+MySQLで簡単なのを作ったりしてるうちに何となく程度に言語の仕様覚えていったり、今出来そうな範囲で今自分がやってることをコードに落とし込んでいくのが一番覚えるのに良いと思うよ。
そうやって出来る事がわかっていけば作りたいものもイメージできるようになるんじゃない?
これを読んで、何をやれば良いのか判らないのはネットやPCを触るに当たってあんまり不自由していない、面倒だと思わないのも一つの原因かもしれない、と思いました。何かする場合には既存の環境を使うし出来ない事はああ出来ないんだ、なら別のを探してなかったら諦めよう、で終わってしまうというか。ようするに、気付く事が出来ない、発想力のない人間は駄目なんですね。
http://anond.hatelabo.jp/20070924223518
確かに最初は何が出来るかが分からないから何を作りたいかも漠然としか思いつかないだろうなぁ、俺もそうだった気がする。
既存の完成しているソフトやらは中身がどうなってるか予想もしづらいし、最初に作りたいと想定するようなもんでもないし。
俺の場合は、昔からやってたサイトがあったから日記とかの管理が面倒だったんでフリーのperlのスクリプト弄ったりPHP+MySQLで簡単なのを作ったりしてるうちに何となく程度に言語の仕様覚えていったり、今出来そうな範囲で今自分がやってることをコードに落とし込んでいくのが一番覚えるのに良いと思うよ。
そうやって出来る事がわかっていけば作りたいものもイメージできるようになるんじゃない?
正直どれもあまり役にたたなそうだなと立ち読みしながら思った。
Perlと同じぐらいの書籍がおいてあるのに書籍のレベルが総じて低い。期待値と未成熟さが同居している。
本を買っただけで、他にはなにもしなかった。
Railsでソーシャルブックマークを作ってみようか(第2回)
http://d.hatena.ne.jp/PoohKid/20070220/p1
これをちろりとやってみた。
ログインしたらIn the Caboose.なるポエムが表示されて変なプラグインいれちゃったのかとかなり反省。
よくわからない。
どうもしくじったようだ……。
とおもったら、できてたみたい。
views/account/index.rhtmlに記述されてた内容がそのまま表示されていたようです。
「エラーが発生しました。詳細についてはエラー・ログを参照してください。」
なんとなく構成はわかったから、そろそろコーディングしてみるか。
昨日買った本を読みながらやっていたのだが、この本がなかなかいい。
少なくとも最初に買った
とは大違い。実用書は現物をある程度見てから買わないとダメだと痛感した。
もし、この本を本屋で立ち読みしてからだったら買わなかっただろう。
やっぱSEはやるなー。秀和ははずすとほんとに本の趣旨がわからなくなる。
engines:なんだろう
Login engine:なんだろう
サンプルとかをみていると変数前に$、@がつく。なんだろう?スコープかな。
$→グローバル
サンプル突っ込んでいわれるがまま設定して500だと不慣れだとどうしていいかわからないよ。
せめて行とかでないものか、どこで設定するのだろうか。
探したがみつからなかった。
Rake Tasksの画面で
db:migrate:enginesと呼び出すところを候補がでないので、
db:migrateでメソッドをenginesにしてしまいなんで失敗するのかわからなかった。
にしてもまいった。こんな時間までがんばってみたが、本当にコーディングにも入れないまま終わりそうだ。
ただのアーリーアダプターな技術オタクにだけ集まられても会社としては考え物じゃない?
ただ、可能性としてはPHP、Ruby、Perlみたいに、Rubyも入れておけば
他よりは目に留まるかもね。
http://rails.jobboard.drecom.jp/
Rubyのコンテストですらこんなレベルでしか求人だしてないし。
でもメイン言語がLLだけって会社に就職するのって技術者にとっては相当ギャンブルじゃない?
あまりいい技術者が集まるとも思えないな。
それくらいできて、LL、OSSどっぷりに足を突っ込むリスクを背負えるんだったらフリーランスでやるだろうし。
というか地方でそういう積極的な姿勢を取れるところがあったら是非紹介してください。
>駄文長文注意<
意識されている「きっかけ」が変なので報告してみる。
プログラミング歴約6年。
小学校高学年くらいから、父の職場で使われてたPC98で、Notepadに文字を打つのが単に好きだった。
なんでだったかよく覚えてないけど。
で、別にプログラムなんか興味なくて、中学校のときに「技術・家庭」の授業でBASICをいじるのが一回だけあって、女の子数人に「すごーい!教えて!」って寄ってこられたのは気分が良かったが、特に面白いとは感じなかった。
高校は世界系とかファンタジーのラノベばっか読んでた。オーフェンとかブギーポップとか、好きだったのはDクラッカーズ。
と言われそうだけど、こういうのが原点だったと自覚している。
小説って世界を数百ページの紙の中に構築するわけだ。
僕は想像力が豊かっていうか、ちょっと”イタイ”人っていうか、
読んだあとはラノベの世界がかなり身近に感じられてもうワクワクがとまらない人だったから、
自分も作り手になりたいと思った。
ほどなく、プログラムも、
「世界を作る」ツールだって認識して興味がわいたのね。
その時分は作れるものがかなり限定されていたけど、
大学もVirtual Realityに興味がわいて工学部に入ったわけで、
VR空間をプログラミングできたら!とか思ったんだ。
まあ多くの方はご存知のとおり、そんな段階じゃないんだよねあの分野は。
大学入ってすぐは社会学に興味もったりしてたわけで、興味はプログラムから離れていた。
一年でJavaのプログラミング授業とかやったけど、別にそんなに楽しくは無かった。
書き忘れたけど、高校のときに図書館の本でHot Soup Processorに触れている。
”日常を変える”プログラミングの楽しさをはじめて知ったのはこれだった。
そんなこんなで苦手ではなかったけど、大学3年のときのプログラミングとかも、
ちんたら遅いし、できることは大して増えないし、面倒だし嫌いだった。
ってか今でもそうだけど、光る箱に一人でカタカタやるってのが性に合わない。
*'``・* 。 | `*。 ,。∩ * こんな感じで + (´・ω・`) *。+゜ `*。 ヽ、 つ *゜* `・+。*・' ゜⊃ +゜ ☆ ∪~ 。*゜ `・+。*・ ゜
プログラム組みたいわけだ。僕は。
で、卒論になって、指導教官の希望順の関係でばりばり情報系のとこに配属されて、
Perlでやることになって、まためんどくさいなぁと思いつつやったわけ。
モジュールを使うことを覚えた分、ちょっと理想に近づいたけどね。
昨日まで彼女がいたりした僕は、大学入って4年間でちょっとはリア充さを身につけたので、
”(虚構)世界を作る”から”日常を変える”ほうに興味は移り、今に至る。
そうそう、高校は家から通学だけで2時間半かかる男子校だし、友達も少ないし、「非リア充」だったから、その状況では、”日常を変える”ことで幸せになるより”世界を作る”ことで幸せになるほうが簡単に思えたのね。
今は逆。
だらだら喋ったけど、結局プログラムは僕にとって手段でしかありません。
最近ホットエントリにあがってるマシン語わかんなきゃいけないとか「はぁ?」って感じ。
*'``・* 。 | `*。 ,。∩ * こんなプログラミング + (´・ω・`) *。+゜ `*。 ヽ、 つ *゜* `・+。*・' ゜⊃ +゜ ☆ ∪~ 。*゜ `・+。*・ ゜
が理想なんだから。
自分の手で作りたい何か、変えたい何かがあるって方が、
僕は組み込み系システムエンジニアなのだけど、自分の業務改善作業がとても好きだ。
キーボードを自腹で買い換えたり、メモリを自腹で増設したり、いろんなツール導入したり、GTD導入したり、職場にwiki導入してみたり、デュアルディスプレイを自腹で構築したり、仕様書とソースコードをPerlやRubyで出力して同時出力したりなど色々業務環境を改善してきた。
自分の開発環境をより開発しやすく、自分の開発工程をより完成度を高くしていく作業はとても楽しい。そういう記事を読むのもかなり好きだ。
でもずっと前からやりたいけどやれないことがある。それはペアプログラミングだ。
理由はペアプログラミングという業務改善作業には、それに賛同してくれる相手が必要で、今この職場には賛同相手は一人もいないからだ。僕の拙い説明では、「どうもペアプログラミングは悪くないらしい」ということが伝わらない。「そんなチャレンジしてる暇があれば目の前の仕事しなよ」と言われてしまう。きっと僕がペアプログラミング未経験者だからうまく説明できないというのもあると思うのだけど。
でも多分、ペアプログラミングは、「コミュニケーション不足になりがち」というIT業務の本質的な欠陥を補い得るかなり根本的な業務改善だと思う。だけど、それでも出来ない。賛同してくれる人が職場に一人もいない。だからペアプログラミングが出来ない。
「仕様書レビュー、ソースコードレビューで十分じゃないか」そう言われてしまう。十分か、十分じゃないかなんて試してみなければわからないじゃないか。
今のところ、地道に「ペアプログラミングやりたいやりたい」とことあるごとに周りに言って回る日々をすごしています。
$,=", "; $\="\n"; $_ = "Hello world"; print scalar(@{[/o/g]}), length;
printを知らないjavascript:
string = 'Hello world'; string.match(/o/g).length+', '+string.length+"\n";
ちょっと趣旨は離れるけれど。他言語はどんな感じ?
http://anond.hatelabo.jp/20070906231939
返事がもらえた。とてもうれしいです。
そうだね。何をやろうかな?Web系ならPerlとRubyとPHPとASPとRDBなら扱ったことがある。でも最近ほとんど使って無いからかなり能力がさび付いていて、最初は役に立てないかもしれないけど、がんばりたい。仕事のプログラムに疲れたら遊びのプログラムをする、やのさとるさんみたいに僕はなりたいと感じます。せっかくITが今ものすごく面白いことになっているのに、これを黙ってみているだけなのは本当にもったいない。
台風の影響で書き込み数とか減るのかな?とか思ったので調べた。
09-04 00 ********** 09-04 01 ******* 09-04 02 ********* 09-04 03 **** 09-04 04 *** 09-04 05 *** 09-04 06 ** 09-04 07 ***** 09-04 08 * 09-04 09 ****** 09-04 10 ****************** 09-04 11 ************************************ 09-04 12 ********************** 09-04 13 *************************** 09-04 14 ********************************************* 09-04 15 ********************************************* 09-04 16 ********************************** 09-04 17 ************************************* 09-04 18 **************** 09-04 19 ************** 09-04 20 ************************** 09-04 21 *********************************** 09-04 22 ****************************************** 09-04 23 *************************** 09-05 00 **************** 09-05 01 ********** 09-05 02 ****** 09-05 03 ********* 09-05 04 **** 09-05 05 ********* 09-05 06 **** 09-05 07 * 09-05 08 ***** 09-05 09 ********************************************* 09-05 10 ******************************************************************************* 09-05 11 ******************** 09-05 12 ************* 09-05 13 ******************************** 09-05 14 ****************************** 09-05 15 ********************************************************************** 09-05 16 ********************************************************************** 09-05 17 ***************** 09-05 18 ******************************** 09-05 19 ************************************* 09-05 20 ********************* 09-05 21 ************************************************ 09-05 22 *************************************************** 09-05 23 ************************************************ 09-06 00 **************************************** 09-06 01 ****** 09-06 02 *** 09-06 03 ************* 09-06 04 ****** 09-06 05 *** 09-06 06 *** 09-06 07 *** 09-06 08 ***** 09-06 09 ***** 09-06 10 ******************************* 09-06 11 ***************************** 09-06 12 ************* 09-06 13 **************************** 09-06 14 ****************** 09-06 15 *********************** 09-06 16 ************************************** 09-06 17 **************************************************************************** 09-06 18 ********************************* 09-06 19 ************* 09-06 20 ********************** 09-06 21 **************************************************** 09-06 22 *************** 09-06 23 ******************** 09-07 00 ************ 09-07 01 **************** 09-07 02 ************** 09-07 03 ********* 09-07 04 ****** 09-07 05 ** 09-07 06 *** 09-07 07 *** 09-07 08 ********** 09-07 09 ************** 09-07 10 *********************** 09-07 11 *********** 09-07 12 ********************* 09-07 13 ************************* 09-07 14 ******************** 09-07 15 ************************************* 09-07 16 *************** 09-07 17 ******** 09-07 18 ********** 09-07 19 ********* 09-07 20 ****** 09-07 21 ********* 09-07 22 *********** 09-07 23 ************** 09-08 00 **** 09-08 01 **************** 09-08 02 **************** 09-08 03 **** 09-08 04 *** 09-08 05 **** 09-08 06 ** 09-08 07 *********** 09-08 08 ******* 09-08 09 ***** 09-08 10 ***** 09-08 11 ************************* 09-08 12 *********** 09-08 13 ******************** 09-08 14 **************** 09-08 15 ******************* 09-08 16 ********************* 09-08 17 ************************************* 09-08 18 ************************* 09-08 19 ****************** 09-08 20 ********** 09-08 21 ************** 09-08 22 ********* 09-08 23 **** 09-09 00 ********* 09-09 01 ************* 09-09 02 **** 09-09 03 ***** 09-09 04 **** 09-09 05 ** 09-09 06 ***** 09-09 07 ***** 09-09 08 ** 09-09 09 *************** 09-09 10 *** 09-09 11 ****************** 09-09 12 ******** 09-09 13 ******** 09-09 14 ************ 09-09 15 ***************** 09-09 16 ******** 09-09 17 **************** 09-09 18 ************* 09-09 19 ************** 09-09 20 ************* 09-09 21 ******************* 09-09 22 ************** 09-09 23 ************ 09-10 00 **************************** 09-10 01 ******************** 09-10 02 ********* 09-10 03 ********** 09-10 04 *** 09-10 05 ** 09-10 06 **** 09-10 07 *** 09-10 08 ***** 09-10 09 ********** 09-10 10 ***************************** 09-10 11 ******************************* 09-10 12 ***************************** 09-10 13 ******************* 09-10 14 ********************** 09-10 15 *********************** 09-10 16 ********************* 09-10 17 ********************************************************** 09-10 18 ******************************************** 09-10 19 ************************* 09-10 20 ********************* 09-10 21 ************************ 09-10 22 ********************************* 09-10 23 ***************
良くわからないけど22ー23が減ってる気もする。つか、やっぱり昼が多いとか、そっちの方が興味深かった。
念為記録
grep Permalink anond20070906.txt | perl -pe '/\b(\d\d):\d\d\b/ and $_="$1\n"' | sort | uniq -c | perl -ne '($n,$d)=split;print "09-06 $d ", "*"x$n, "\n"' > anondgraph.txt
最近perlの勉強してて、naoyaのはてなダイアリー - Web::ScraperでWeb::Scraperを知り、試しにはてブのAPIを真似してニフティクリップのコメントを吐くJSONを作った。
#!/usr/local/bin/perl -T # # use strict; use warnings; use URI; use Web::Scraper; use JSON::XS; use CGI; use Encode; my $q = new CGI; print $q->header( -type=>'text/plain', -charset=>'UTF-8'); my $path_info = $q->path_info; my $path = $path_info =~ m{^/?(nobracket/)?(http\w?)://?(.*)$}xms ? $2.'://'.$3 : undef ; exit if ! $path; my $is_nobracket = 'true' if $1; if ($q->query_string) { my $query_string = $q->query_string; $query_string =~ s/;/&/g; $path = $path.'?'.$query_string } $path =~ s/%23/#/; $path =~ s/([^\w ])/'%' . unpack('H2', $1)/eg; $path =~ tr/ /+/; my $entry_url = "http://clip.nifty.com/entry/?url=" . $path; my $bookmarks = scraper { process 'h4>a', 'user' => 'TEXT'; process 'li.dateAndTime', 'timestamp' => 'TEXT'; process 'a.tagtag', 'tags[]' => sub { my $text = $_->as_text or return; my $left = decode_utf8('??~P'); my $right = decode_utf8('??~Q'); return $text =~ /$left (.*?) $right/xms; }; process 'p.comment', 'comment' => 'TEXT'; result 'user', 'timestamp', 'tags', 'comment'; }; my $niftyclip_entry_info = scraper { process 'div.clipTitle>h3>a', 'title' => 'TEXT'; process 'div.clipTitle>p.url>a', 'url' => '@href'; process 'div.comments>div.commentsDetails', 'bookmarks[]' => $bookmarks; result 'title','url','bookmarks'; }; my $niftyclip = scraper { process 'div#content', 'niftyclip_entry' => $niftyclip_entry_info; result 'niftyclip_entry'; }->scrape(URI->new($entry_url)); exit if ! ($niftyclip->{'url'}); $niftyclip->{'entry_url'} = $entry_url; $niftyclip->{'count'} = @{$niftyclip->{'bookmarks'}}; my $json = JSON::XS->new->utf8->encode($niftyclip); $json = '('. $json. ')' if ! $is_nobracket; print $json;
取得方法は
http://monm.on.coocan.jp/niftyclip/json/entry/<取得したいURL>
ってすればいい。「#」は「%23」にエスケープしないとダメ。
作りながら「取得したいURLをURLエンコードするのは面倒だな」って思い、はてブのAPIみたいにpath_infoでアクセスできるようにしたわけだけど、その取得したいURLにquery_stringが付いてた場合にどうやってやって良いかわからず結構悩んだ。
結局、path_info+'&'+query_stringってやることで無理やり作ったけど、普通どうやるもんなんだろ?cpanに何か良いモジュールがあったりするのかな。
それと、はてブに合わせて出力の際に()を付けるようにしたけど、これだとYahoo!Pipesで使えなかったから、
http://monm.on.coocan.jp/niftyclip/json/entry/nobracket/<取得したいURL>
みたいに「nobracket」付きでアクセスした場合には()を付けないようにした。
コレ使うとニフティクリップとlivedoor クリプのコメント取ってくるAPIみたいなのが作れる。
RSSで取得する場合は
http://pipes.yahoo.com/pipes/pipe.run?_id=zECBJ_VY3BGtBw6B8ivLAg&_render=rss&URL=<URLエンコードしたURL>
で取得できるし、jsonで取得する場合は
http://pipes.yahoo.com/pipes/pipe.run?_id=zECBJ_VY3BGtBw6B8ivLAg&_render=json&URL=<URLエンコードしたURL>
ってなる。
とりあえずサクッと作ってみたけど、わざわざページからJSON作ってるからちょっと重い。
その頃にはJSON吐いてくれるようになるんじゃないかなと期待はしてるけど。
参考URL:
これから就職活動するバカはいないだろうけど、そういう人もいるだろうから少し書いておこう。
どちらかというと、アンチMS派なUnix技術者がWindowsだけの世界で仕事をする辛さを。
Unix技術者は、業務実績にSolaris/AIX/Linuxって書いてあってもちゃんと質問しろ。Windowsの仕事は無いですよね?って。
僕が食べるために職を手にしているこのIT業界というのは、バッドノウハウとMicroSoftとExcelで出来ている。
その為、僕が手にしたUnixの知識は、特定の仕事以外でしか役に立たないし、使わない。
viだろうが、TeXだろうが、Xの知識よりも、MFCとVBAのちょっとした知識のあるヤツが上にみられる。
ExcelとWindowsの知識があればそれだけで仕事になるからだ。
いいか、viやTeX、Xなんて捨てちまえ、Excelがあればそれでいいのだ。
MSでは、ActiveXを使ってCOMを操作し、クライアントのレジストリを操作し、IE単体でできないことをやってしまうヤツがハッカーと思われている。
VBAマクロで作ったなんちゃってツールを3時間で作れるほうが、
perlやruby/pythonで、より少ない時間で作ったツールよりも凄く思われてしまう。
そして、それができるヤツの方が、Unix技術者よりもよりハッカーであり、技術力があると思われている。
ブラウザを例にしたが、
javascriptでalert/confirmを出すよりも、vbscriptでMsgBoxの方が多くのことができるから、
javascriptでNumberの計算よりも、vbscriptでDecimalを使った方が倍密度の計算ができるから、
vbscriptを駆使できるヤツは、凄く重宝される。
いいか、javascriptで汎用的に書くのなんてナンセンスだ。javascriptなんて捨てちまえ、覚えるのはJScript実装(WSH)だ。
この業界、何が不満になるかというと、
MSの、もっというとWindowsのことしか知らないヤツが多すぎるということ。
そういうヤツらは、Windowsだったらこんなこともできるのに、なぜUnix/Linuxだとこんなこともできないのか。と言う
そういうヤツらは、Windowsの未修正バグの合間を縫いながら中途半端な実装しかしない。
だって、中途半端(もしくは大雑把)な実装で動いているものの中で動くから。それ以上に実装しようとしてもできないのだ。
いいか、win32のメッセージングの仕組を覚えるんだ。無理矢理send_keyみたいなコードを書けるようにしろ。
コマンドを連結するよりも、結果に近いコードを書くんだ。線形になろうがヤツらは気にしないだろう。
何故か。
それは、.NETで作ればお客さんの要望が実現でき、Excelと連携できるからだ。
ヤツらは、C/Sの世界でこそ役に立つ技術者だが、Webの世界に連れてきてはならない。すぐに実装がIEだけになる。
ヤツらにLLを覚えさせるのは無理だ。
クロージャなんて知らないし、高階関数やカリーなんてコードを教えてみろ。後から辛くなるのは自分だ。
ヤツらにはPHPを教えておけ、それだけで満足する。すごいヤツになった気にさせれる。
バッドノウハウ慣れしているヤツらはそれを使ってコードを書いてもらえ、rubyで書かせるよりも修正が20倍楽だ。
いいか、まとめるぞ。
今まで一生懸命Unixを勉強してきたのは無駄だ。いますぐ忘れるんだ。
Excelを今から覚えろ。VBAを覚えろ。そしてMSの動きを身に着けるんだ。
Windowsでは単位がFormだ。それが標準出力と標準入力と思え。ときどきSheetとかWorkbookになるぞ。
ストリームやファイル操作には気をつけろ。Unixの気分でいると思わぬところで抜けが出るぞ。
IRCは使うな。Jabberを使うな。メッセンジャーを使え。移行のお薦めはGaimだ。Windows版がある。
viの使用頻度を減らせ、変なコマンドを身に着ける前に、秀丸マクロを書けるようにしろ、Notepadのショートカットを覚えとけ。
BindとかApache(Httpd)の知識はいらない。IISだ。ActiveDirectoryだ。
文字コードはCp943cを何がなんでも押せ。Shift_JISっていう大雑把な伝えかたはダメだ。絶対cp943cにしろ。UTF8/UTF7との格闘で身も心もぼろぼろになるぞ。
汎用性なんて無いんだ。Windowsというプラットフォームがあれば。
ああ、心が渇いていく。
@data=(a,b,c);print@data
#!/usr/bin/perl use strict; my @data = qw(a b c); my $cx = scalar @data; my $si = 0; my $ax; LOOP: $ax = $data[$si]; print $ax; $si++; not --$cx or goto LOOP;
#!/usr/bin/perl use strict; my @data = qw(a b c); package AtoH; use base qw(Tie::Handle); sub TIEHANDLE { my $class = shift; return bless {data => [@_]}, $class; } sub READLINE { return shift @{shift->{data}}; } package main; tie *ARGV, 'AtoH', @data; while (<>) { print; }
まずは最短コース。(use strict;なんて使っちゃだめよ)
@data = qw(a b c);print(@data);
次にややこしいコース
#!/usr/bin/perl use strict; my @data = qw(a b c); sub nextMember(@) { my $datum = shift(@_); if($datum){ print($datum); nextMember(@_); } return; } nextMember(@data);
dataは複数形だから、datasなんて認めないぞ僕は。
■X-Reproxy-Cache-Clear できる Perlbal プラグインCommentsAdd Star
■[Perl][CPAN][Perlbal] X-REPROXY-CACHE-FORを使いたい人向けショートBK
X-REPROXY-CACHE-FOR ヘッダが Perlbal に(というか Perlbal::Cache に)どのように解釈されるかというと、
1467 sub add_to_reproxy_url_cache {
1468 my Perlbal::Service $self;
1469 my ($reqhd, $reshd);
1470
1471 ($self, $reqhd, $reshd) = @_;
1472
(snip)
1484 my $hostname = $reqhd->header("Host") || '';
1485 my $requri = $reqhd->request_uri || '';
1486 my $key = "$hostname|$requri";
1487
(snip)
1496 $cache->set($key, [$timeout, \@headers, $urls]);
1497 }
こうなってる。ここで、
Perlbal -> mod_perl -> MogileFS
こんな風に、フロントに Perlbal, バックエンドに mod_perl ハンドラでも置いて、その裏の MogileFS とやりとり(をあんまさせたくないので Perlbal に直にキャッシュさせたい)という構成を考える。
この場合、
つまり、
X-REPROXY-CACHE-CLEAR: /artwork/12345
というヘッダを mod_perl から Perlbal に返す必要がある(host は補われる)
この /artwork/12345 というリクエスト URL は、 mod_perl 側から直に参照できない。
mod_perl ハンドラを例えば以下のような conf であてていたとすると、
<Location /example/artwork>
PerlHandler Example::Artwork
</Location>
RewriteEngine On
RewriteRule ^/artwork/(.*) http://127.0.0.1:8080/example/artwork/$1 [P,L]
ここで $r->uri をとると /example/artwork/12345 となり、これをそのまま X-REPROXY-CACHE-CLEAR で返しても Perlbal::Cache がキャッシュした key とは違うものなのでキャッシュを破棄できない。自前で $r->uri を split なりして、 /artwork/12345 を、 Rewrite される前の URL を知る必要がある。当然、どんな RewriteRule かに依存するので一般的な実装はあげられない。 Rewrite しなければもう少し話が簡単になる。
要は、
と、それぞれ意味の違った URL (key になるもの)がいくつか存在して、どれがどれやらわからなくなってしまうので、ハマりどころが多い。ありがちな(というか俺がやった)ミスとしては、 CACHE-FOR でキャッシュした状態で MogileFS からファイル実体を消してしまうと (mogile に突っ込むときの key はまた別に digest とかで作ってあったりすると余計に混乱することうけあい) Mogile にはもう存在せず、したがって mod_perl にはどうしたって知りようがない URL を Perlbal がキャッシュしていて 503 を返しつづける、という状態になってしまう。それから、キャッシュを自発的に消したいときというのはもともとキャッシュしてた URL (Mogile 上でのファイルのありか)が指し示すファイル実体を消したいときなので(実体がないものをいつまでもキャッシュしているのは困る、という理由)当然実体そのものも消すわけだが、
こういう手順でつくらないといけない。この URL は ACL を厳重にしておかないと、全ての artwork に対応するキャッシュ破棄用(つまりファイル削除用) URL を GET されまくってファイルを消されまくってしまうので非常にまずい。
我ながら乱雑で要領を得ない文章だと思うけど、こんなものでもないよりはあったほうがこれから同じことをやろうとする人にとっては多少の助けになると思うので走り書きのままで公開する。こういう、どっかに一言書いてあれば5秒でぐぐって済むことを何時間もかけてやり直すのは人類にとっての時間的損失でばからしいので、適当に間違ってるところとかを修正しつついろんなブログとかに転載しまくって世に広めてください。
http://anond.hatelabo.jp/20070803143914
(*)このエントリでは増田がとっても感情的になって、C言語、SQL、JScript, JavaScript, Perlをけなす風潮に反発します。
確かにプログラミング言語やその周辺の技術は目的を達成するための手段でしかないのかもしれない。けれど、その手段を行使できるようになるために一週間そこらドキュメントやサンプルを読み書きするだけでおkな人って実在するのか?JavaやCにしたってどれだけ標準搭載の関数やらAPIがあると思っているんだ?そりゃあ実装に必要な部分さえ分かればいいんだろうけど、、。ぐすん。
俺はオブジェクト指向を肌で感じ取れるようになるまで1年以上かかったが、それでも完全に理解できているといえるのかよく分からない。それを一週間程度で理解できるだとおぉぉ、許せん、嫉妬してやるぅ。
ついでに言うと、誰でもできる仕事を一般化してプログラムに落とし込むのがプログラマの仕事だあああ、、、、とも思う、、、、うん、思うだけ。中学生にでもできるといいながら、人間に外注するってどういうことよ。誰でもできるんならパソコンに頼めよ。そういうプログラムを組めよ。優秀な人はコンパイラとか作れるんでしょ。もっと言えば、プリミティブな部分とやらを最初からプログラミング言語でしゃべっておけば、外注すら必要ないよ。外国の人を作業するとき英語でコミュニケーションとるでしょ?システムの設計とかもプログラミング言語でやれば?まさか日本語で適当に要件定義書書いて、外注に丸投げとか言わないよね。それとも、優秀な人はみんな理論屋になるってこと?
ぐすん、、ぐすん、、そりゃあさ、僕はHDLでCPU設計とか、 Yacc/Lexでコンパイラ作成とか、OS作成とかやったことないし、できないよ。C/C++だってDirectXの3Dに関わる理論とオブジェクト指向が分からなくて挫折したよ。XoopsみたいなCMS作ろうとして要件定義や設計がぜんぜんできなくて挫折したよ。要件を決めずにプログラム組んでたら、後から次々と要求変更を思いついてしまって、手が回らなくなって頓挫したよ。データベース設計もまともにできないしSQL?なにそれって感じだよ。電子回路?トランジスタの使い方・つなぎ方とか、増幅率とかがうまく計算できなくて挫折したよ。
だから(?)「Perlなんて簡単だよね。そんなものにしがみついてるなんてレベル低いなお前」みたいなこと言うおまえなんか大嫌いだ。
/* Ten */ if (typeof(Ten) == 'undefined') { Ten = {}; } Ten.NAME = 'Ten'; Ten.VERSION = 0.06; /* Ten.Class */ Ten.Class = function(klass, prototype) { if (klass && klass.initialize) { var c = klass.initialize; } else if(klass && klass.base) { var c = function() { return klass.base[0].apply(this, arguments) }; } else { var c = function() {}; } c.prototype = prototype || {}; c.prototype.constructor = c; Ten.Class.inherit(c, klass); if (klass && klass.base) { for (var i = 0; i < klass.base.length; i++) { var parent = klass.base[i]; if (i == 0) { c.SUPER = parent; c.prototype.SUPER = parent.prototype; } Ten.Class.inherit(c, parent); Ten.Class.inherit(c.prototype, parent.prototype); } } return c; } Ten.Class.inherit = function(child,parent) { for (var prop in parent) { if (typeof(child[prop]) != 'undefined' || prop == 'initialize') continue; child[prop] = parent[prop]; } } /* // Basic Ten Classes **/ /* Ten.JSONP */ Ten.JSONP = new Ten.Class({ initialize: function(uri,obj,method) { if (Ten.JSONP.Callbacks.length) { setTimeout(function() {new Ten.JSONP(uri,obj,method)}, 500); return; } var del = uri.match(/\?/) ? '&' : '?'; uri += del + 'callback=Ten.JSONP.callback'; if (!uri.match(/timestamp=/)) { uri += '&' + encodeURI(new Date()); } if (obj && method) Ten.JSONP.addCallback(obj,method); this.script = document.createElement('script'); this.script.src = uri; this.script.type = 'text/javascript'; document.getElementsByTagName('head')[0].appendChild(this.script); }, addCallback: function(obj,method) { Ten.JSONP.Callbacks.push({object: obj, method: method}); }, callback: function(args) { // alert('callback called'); var cbs = Ten.JSONP.Callbacks; for (var i = 0; i < cbs.length; i++) { var cb = cbs[i]; cb.object[cb.method].call(cb.object, args); } Ten.JSONP.Callbacks = []; }, MaxBytes: 8000, Callbacks: [] }); /* Ten.XHR */ Ten.XHR = new Ten.Class({ initialize: function(uri,opts,obj,method) { if (!uri) return; this.request = Ten.XHR.getXMLHttpRequest(); this.callback = {object: obj, method: method}; var xhr = this; var prc = this.processReqChange; this.request.onreadystatechange = function() { prc.apply(xhr, arguments); } var method = opts.method || 'GET'; this.request.open(method, uri, true); if (method == 'POST') { this.request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); } var data = opts.data ? Ten.XHR.makePostData(opts.data) : null; this.request.send(data); }, getXMLHttpRequest: function() { var xhr; var tryThese = [ function () { return new XMLHttpRequest(); }, function () { return new ActiveXObject('Msxml2.XMLHTTP'); }, function () { return new ActiveXObject('Microsoft.XMLHTTP'); }, function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); }, ]; for (var i = 0; i < tryThese.length; i++) { var func = tryThese[i]; try { xhr = func; return func(); } catch (e) { //alert(e); } } return xhr; }, makePostData: function(data) { var pairs = []; var regexp = /%20/g; for (var k in data) { var v = data[k].toString(); var pair = encodeURIComponent(k).replace(regexp,'+') + '=' + encodeURIComponent(v).replace(regexp,'+'); pairs.push(pair); } return pairs.join('&'); } },{ processReqChange: function() { var req = this.request; if (req.readyState == 4) { if (req.status == 200) { var cb = this.callback; cb.object[cb.method].call(cb.object, req); } else { alert("There was a problem retrieving the XML data:\n" + req.statusText); } } } }); /* Ten.Observer */ Ten.Observer = new Ten.Class({ initialize: function(element,event,obj,method) { var func = obj; if (typeof(method) == 'string') { func = obj[method]; } this.element = element; this.event = event; this.listener = function(event) { return func.call(obj, new Ten.Event(event || window.event)); } if (this.element.addEventListener) { if (this.event.match(/^on(.+)$/)) { this.event = RegExp.$1; } this.element.addEventListener(this.event, this.listener, false); } else if (this.element.attachEvent) { this.element.attachEvent(this.event, this.listener); } } },{ stop: function() { if (this.element.removeEventListener) { this.element.removeEventListener(this.event,this.listener,false); } else if (this.element.detachEvent) { this.element.detachEvent(this.event,this.listener); } } }); /* Ten.Event */ Ten.Event = new Ten.Class({ initialize: function(event) { this.event = event; }, keyMap: { 8:"backspace", 9:"tab", 13:"enter", 19:"pause", 27:"escape", 32:"space", 33:"pageup", 34:"pagedown", 35:"end", 36:"home", 37:"left", 38:"up", 39:"right", 40:"down", 44:"printscreen", 45:"insert", 46:"delete", 112:"f1", 113:"f2", 114:"f3", 115:"f4", 116:"f5", 117:"f6", 118:"f7", 119:"f8", 120:"f9", 121:"f10", 122:"f11", 123:"f12", 144:"numlock", 145:"scrolllock" } },{ mousePosition: function() { if (!this.event.clientX) return; return Ten.Geometry.getMousePosition(this.event); }, isKey: function(name) { var ecode = this.event.keyCode; if (!ecode) return; var ename = Ten.Event.keyMap[ecode]; if (!ename) return; return (ename == name); }, targetIsFormElements: function() { var target = this.event.target; if (!target) return; var T = (target.tagName || '').toUpperCase(); return (T == 'INPUT' || T == 'SELECT' || T == 'OPTION' || T == 'BUTTON' || T == 'TEXTAREA'); }, stop: function() { var e = this.event; if (e.stopPropagation) { e.stopPropagation(); e.preventDefault(); } else { e.cancelBubble = true; e.returnValue = false; } } }); /* Ten.DOM */ Ten.DOM = new Ten.Class({ getElementsByTagAndClassName: function(tagName, className, parent) { if (typeof(parent) == 'undefined') { parent = document; } var children = parent.getElementsByTagName(tagName); if (className) { var elements = []; for (var i = 0; i < children.length; i++) { var child = children[i]; var cls = child.className; if (!cls) { continue; } var classNames = cls.split(' '); for (var j = 0; j < classNames.length; j++) { if (classNames[j] == className) { elements.push(child); break; } } } return elements; } else { return children; } }, removeEmptyTextNodes: function(element) { var nodes = element.childNodes; for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) { node.parentNode.removeChild(node); } } }, nextElement: function(elem) { do { elem = elem.nextSibling; } while (elem && elem.nodeType != 1); return elem; }, prevElement: function(elem) { do { elem = elem.previousSibling; } while (elem && elem.nodeType != 1); return elem; }, scrapeText: function(node) { var rval = []; (function (node) { var cn = node.childNodes; if (cn) { for (var i = 0; i < cn.length; i++) { arguments.callee.call(this, cn[i]); } } var nodeValue = node.nodeValue; if (typeof(nodeValue) == 'string') { rval.push(nodeValue); } })(node); return rval.join(''); }, onLoadFunctions: [], loaded: false, timer: null, addEventListener: function(event,func) { if (event != 'load') return; Ten.DOM.onLoadFunctions.push(func); Ten.DOM.checkLoaded(); }, checkLoaded: function() { var c = Ten.DOM; if (c.loaded) return true; if (document && document.getElementsByTagName && document.getElementById && document.body) { if (c.timer) { clearInterval(c.timer); c.timer = null; } for (var i = 0; i < c.onLoadFunctions.length; i++) { c.onLoadFunctions[i](); } c.onLoadFunctions = []; c.loaded = true; } else { c.timer = setInterval(c.checkLoaded, 13); } } }); /* Ten.Style */ Ten.Style = new Ten.Class({ applyStyle: function(elem, style) { for (prop in style) { elem.style[prop] = style[prop]; } } }); /* Ten.Geometry */ Ten.Geometry = new Ten.Class({ initialize: function() { if (Ten.Geometry._initialized) return; var func = Ten.Geometry._functions; var de = document.documentElement; if (window.innerWidth) { func.getWindowWidth = function() { return window.innerWidth; } func.getWindowHeight = function() { return window.innerHeight; } func.getXScroll = function() { return window.pageXOffset; } func.getYScroll = function() { return window.pageYOffset; } } else if (de && de.clientWidth) { func.getWindowWidth = function() { return de.clientWidth; } func.getWindowHeight = function() { return de.clientHeight; } func.getXScroll = function() { return de.scrollLeft; } func.getYScroll = function() { return de.scrollTop; } } else if (document.body.clientWidth) { func.getWindowWidth = function() { return document.body.clientWidth; } func.getWindowHeight = function() { return document.body.clientHeight; } func.getXScroll = function() { return document.body.scrollLeft; } func.getYScroll = function() { return document.body.scrollTop; } } Ten.Geometry._initialized = true; }, _initialized: false, _functions: {}, getScroll: function() { if (!Ten.Geometry._initialized) new Ten.Geometry; return { x: Ten.Geometry._functions.getXScroll(), y: Ten.Geometry._functions.getYScroll() }; }, getMousePosition: function(pos) { // pos should have clientX, clientY same as mouse event if ((navigator.userAgent.indexOf('Safari') > -1) && (navigator.userAgent.indexOf('Version/') < 0)) { return { x: pos.clientX, y: pos.clientY }; } else { var scroll = Ten.Geometry.getScroll(); return { x: pos.clientX + scroll.x, y: pos.clientY + scroll.y }; } }, getElementPosition: function(e) { return { x: e.offsetLeft, y: e.offsetTop }; }, getWindowSize: function() { if (!Ten.Geometry._initialized) new Ten.Geometry; return { w: Ten.Geometry._functions.getWindowWidth(), h: Ten.Geometry._functions.getWindowHeight() }; } }); /* Ten.Position */ Ten.Position = new Ten.Class({ initialize: function(x,y) { this.x = x; this.y = y; }, subtract: function(a,b) { return new Ten.Position(a.x - b.x, a.y - b.y); } }); /* // require Ten.js **/ /* Ten.SubWindow */ Ten.SubWindow = new Ten.Class({ initialize: function() { var c = this.constructor; if (c.singleton && c._cache) { return c._cache; } var div = document.createElement('div'); Ten.Style.applyStyle(div, Ten.SubWindow._baseStyle); Ten.Style.applyStyle(div, c.style); this.window = div; this.addContainerAndCloseButton(); document.body.appendChild(div); if (c.draggable) { this._draggable = new Ten.Draggable(div, this.handle); } if (c.singleton) c._cache = this; return this; }, _baseStyle: { color: '#000', position: 'absolute', display: 'none', zIndex: 2, left: 0, top: 0, backgroundColor: '#fff', border: '1px solid #bbb' }, style: { padding: '2px', textAlign: 'center', borderRadius: '6px', MozBorderRadius: '6px', width: '100px', height: '100px' }, handleStyle: { position: 'absolute', top: '0px', left: '0px', backgroundColor: '#f3f3f3', borderBottom: '1px solid #bbb', width: '100%', height: '30px' }, containerStyle: { margin: '32px 0 0 0', padding: '0 10px' }, // closeButton: 'close.gif', closeButton: 'http://s.hatena.com/images/close.gif', closeButtonStyle: { position: 'absolute', top: '8px', right: '10px', cursor: 'pointer' }, _baseScreenStyle: { position: 'absolute', top: '0px', left: '0px', display: 'none', zIndex: 1, overflow: 'hidden', width: '100%', height: '100%' }, screenStyle: {}, showScreen: true, singleton: true, draggable: true, _cache: null },{ screen: null, windowObserver: null, visible: false, addContainerAndCloseButton: function() { var win = this.window; var c = this.constructor; var div = document.createElement('div'); win.appendChild(div); Ten.Style.applyStyle(div, c.containerStyle); this.container = div; if (c.handleStyle) { var handle = document.createElement('div'); Ten.Style.applyStyle(handle, c.handleStyle); win.appendChild(handle); this.handle = handle; } if (c.closeButton) { var btn = document.createElement('img'); btn.src = c.closeButton; btn.alt = 'close'; Ten.Style.applyStyle(btn, c.closeButtonStyle); win.appendChild(btn); new Ten.Observer(btn, 'onclick', this, 'hide'); this.closeButton = btn; } if (c.showScreen) { var screen = document.createElement('div'); Ten.Style.applyStyle(screen, Ten.SubWindow._baseScreenStyle); Ten.Style.applyStyle(screen, c.screenStyle); document.body.appendChild(screen); this.screen = screen; new Ten.Observer(screen, 'onclick', this, 'hide'); } }, show: function(pos) { pos = (pos.x && pos.y) ? pos : {x:0, y:0}; with (this.window.style) { display = 'block'; left = pos.x + 'px'; top = pos.y + 'px'; } if (this.screen) { with (this.screen.style) { display = 'block'; left = Ten.Geometry.getScroll().x + 'px'; top = Ten.Geometry.getScroll().y + 'px'; } } this.windowObserver = new Ten.Observer(document.body, 'onkeypress', this, 'handleEscape'); this.visible = true; }, handleEscape: function(e) { if (!e.isKey('escape')) return; this.hide(); }, hide: function() { if (this._draggable) this._draggable.endDrag(); this.window.style.display = 'none'; if (this.screen) this.screen.style.display = 'none'; if (this.windowObserver) this.windowObserver.stop(); this.visible = false; } }); /* Ten.Draggable */ Ten.Draggable = new Ten.Class({ initialize: function(element,handle) { this.element = element; this.handle = handle || element; this.startObserver = new Ten.Observer(this.handle, 'onmousedown', this, 'startDrag'); this.handlers = []; } },{ startDrag: function(e) { if (e.targetIsFormElements()) return; this.delta = Ten.Position.subtract( e.mousePosition(), Ten.Geometry.getElementPosition(this.element) ); this.handlers = [ new Ten.Observer(document, 'onmousemove', this, 'drag'), new Ten.Observer(document, 'onmouseup', this, 'endDrag'), new Ten.Observer(this.element, 'onlosecapture', this, 'endDrag') ]; e.stop(); }, drag: function(e) { var pos = Ten.Position.subtract(e.mousePosition(), this.delta); Ten.Style.applyStyle(this.element, { left: pos.x + 'px', top: pos.y + 'px' }); e.stop(); }, endDrag: function(e) { for (var i = 0; i < this.handlers.length; i++) { this.handlers[i].stop(); } if(e) e.stop(); } }); /* Hatena */ if (typeof(Hatena) == 'undefined') { Hatena = {}; } /* Hatena.User */ Hatena.User = new Ten.Class({ initialize: function(name) { this.name = name; }, getProfileIcon: function(name) { if (!name) name = 'user'; var pre = name.match(/^[\w-]{2}/)[0]; var img = document.createElement('img'); img.src = 'http://www.hatena.ne.jp/users/' + pre + '/' + name + '/profile_s.gif'; img.alt = name; img.setAttribute('class', 'profile-icon'); img.setAttribute('width','16px'); img.setAttribute('height','16px'); with (img.style) { margin = '0 3px'; border = 'none'; verticalAlign = 'middle'; } return img; } }, { profileIcon: function() { return Hatena.User.getProfileIcon(this.name); } }); /* Hatena.Star */ if (typeof(Hatena.Star) == 'undefined') { Hatena.Star = {}; } /* // Hatena.Star.* classes // **/ if (window.location && window.location.host.match(/hatena\.com/)) { Hatena.Star.BaseURL = 'http://s.hatena.com/'; } else { Hatena.Star.BaseURL = 'http://s.hatena.ne.jp/'; } Hatena.Star.Token = null; /* Hatena.Star.User */ Hatena.Star.User = new Ten.Class({ base: [Hatena.User], initialize: function(name) { if (Hatena.Star.User._cache[name]) { return Hatena.Star.User._cache[name]; } else { this.name = name; Hatena.Star.User._cache[name] = this; return this; } }, _cache: {} },{ userPage: function() { return Hatena.Star.BaseURL + this.name + '/'; } }); /* Hatena.Star.Entry */ Hatena.Star.Entry = new Ten.Class({ initialize: function(e) { this.entry = e; this.uri = e.uri; this.title = e.title; this.star_container = e.star_container; this.comment_container = e.comment_container; this.stars = []; this.comments = []; }, maxStarCount: 11 },{ flushStars: function() { this.stars = []; this.star_container.innerHTML = ''; }, bindStarEntry: function(se) { this.starEntry = se; for (var i = 0; i < se.stars.length; i++) { if (typeof(se.stars[i]) == 'number') { this.stars.push(new Hatena.Star.InnerCount(se.stars[i],this)); } else { this.stars.push(new Hatena.Star.Star(se.stars[i])); } } if (se.comments && !this.comments.length) { for (var i = 0; i < se.comments.length; i++) { this.comments.push(new Hatena.Star.Comment(se.comments[i])); } } this.can_comment = se.can_comment; }, setCanComment: function(v) { this.can_comment = v; }, showButtons: function() { this.addAddButton(); this.addCommentButton(); }, addAddButton: function() { if (this.star_container) { this.addButton = new Hatena.Star.AddButton(this); this.star_container.appendChild(this.addButton); } }, addCommentButton: function() { if (this.comment_container) { this.commentButton = new Hatena.Star.CommentButton(this); this.comment_container.appendChild(this.commentButton.img); } }, showStars: function() { var klass = this.constructor; // if (this.stars.length > klass.maxStarCount) { // var ic = new Hatena.Star.InnerCount(this.stars.slice(1,this.stars.length)); // this.star_container.appendChild(this.stars[0]); // this.star_container.appendChild(ic); // this.star_container.appendChild(this.stars[this.stars.length - 1]); // } else { for (var i = 0; i < this.stars.length; i++) { this.star_container.appendChild(this.stars[i]); } }, showCommentButton: function() { if (this.can_comment) { this.commentButton.show(); if (this.comments.length) this.commentButton.activate(); } else { // this.commentButton.hide(); } }, addStar: function(star) { this.stars.push(star); this.star_container.appendChild(star); }, addComment: function(com) { if (!this.comments) this.comments = []; if (this.comments.length == 0) { this.commentButton.activate(); } this.comments.push(com); }, showCommentCount: function() { this.comment_container.innerHTML += this.comments.length; } }); /* Hatena.Star.Button */ Hatena.Star.Button = new Ten.Class({ createButton: function(args) { var img = document.createElement('img'); img.src = args.src; img.alt = img.title = args.alt; with (img.style) { cursor = 'pointer'; margin = '0 3px'; padding = '0'; border = 'none'; verticalAlign = 'middle'; } return img; } }); /* Hatena.Star.AddButton */ Hatena.Star.AddButton = new Ten.Class({ base: ['Hatena.Star.Button'], initialize: function(entry) { this.entry = entry; this.lastPosition = null; var img = Hatena.Star.Button.createButton({ src: Hatena.Star.AddButton.ImgSrc, alt: 'Add Star' }); this.observer = new Ten.Observer(img,'onclick',this,'addStar'); this.img = img; return img; }, ImgSrc: Hatena.Star.BaseURL + 'images/add.gif' },{ addStar: function(e) { this.lastPosition = e.mousePosition(); var uri = Hatena.Star.BaseURL + 'star.add.json?uri=' + encodeURIComponent(this.entry.uri) + '&title=' + encodeURIComponent(this.entry.title); if (Hatena.Star.Token) { uri += '&token=' + Hatena.Star.Token; } new Ten.JSONP(uri, this, 'receiveResult'); }, receiveResult: function(args) { var name = args ? args.name : null; if (name) { this.entry.addStar(new Hatena.Star.Star({name: name})); //alert('Succeeded in Adding Star ' + args); } else if (args.errors) { var pos = this.lastPosition; pos.x -= 10; pos.y += 25; var scroll = Ten.Geometry.getScroll(); var scr = new Hatena.Star.AlertScreen(); var alert = args.errors[0]; scr.showAlert(alert, pos); } } }); /* Hatena.Star.CommentButton */ Hatena.Star.CommentButton = new Ten.Class({ base: ['Hatena.Star.Button'], initialize: function(entry) { this.entry = entry; this.lastPosition = null; var img = Hatena.Star.Button.createButton({ src: Hatena.Star.CommentButton.ImgSrc, alt: 'Comments' }); img.style.display = 'none'; this.observer = new Ten.Observer(img,'onclick',this,'showComments'); this.img = img; }, ImgSrc: Hatena.Star.BaseURL + 'images/comment.gif', ImgSrcActive: Hatena.Star.BaseURL + 'images/comment_active.gif' },{ showComments: function(e) { if (!this.screen) this.screen = new Hatena.Star.CommentScreen(); this.screen.bindEntry(this.entry); var pos = e.mousePosition(); pos.y += 25; this.screen.showComments(this.entry, pos); }, hide: function() { this.img.style.display = 'none'; }, show: function() { this.img.style.display = 'inline'; }, activate: function() { this.show(); this.img.src = Hatena.Star.CommentButton.ImgSrcActive; } }); /* Hatena.Star.Star */ Hatena.Star.Star = new Ten.Class({ initialize: function(args) { if (args.img) { this.img = args.img; this.name = this.img.getAttribute('alt'); } else { this.name = args.name; var img = document.createElement('img'); img.src = Hatena.Star.Star.ImgSrc; img.alt = this.name; with (img.style) { padding = '0'; border = 'none'; } this.img = img; } new Ten.Observer(this.img,'onmouseover',this,'showName'); new Ten.Observer(this.img,'onmouseout',this,'hideName'); if (this.name) { this.user = new Hatena.Star.User(this.name); this.img.style.cursor = 'pointer'; new Ten.Observer(this.img,'onclick',this,'goToUserPage'); } if (args.count && args.count > 1) { var c = document.createElement('span'); c.setAttribute('class', 'hatena-star-inner-count'); Ten.Style.applyStyle(c, Hatena.Star.InnerCount.style); c.innerHTML = args.count; var s = document.createElement('span'); s.appendChild(img); s.appendChild(c); return s; } else { return this.img; } }, ImgSrc: Hatena.Star.BaseURL + 'images/star.gif' },{ showName: function(e) { if (!this.screen) this.screen = new Hatena.Star.NameScreen(); var pos = e.mousePosition(); pos.x += 10; pos.y += 25; this.screen.showName(this.name, pos); }, hideName: function() { if (!this.screen) return; this.screen.hide(); }, goToUserPage: function() { window.location = this.user.userPage(); } }); /* Hatena.Star.InnerCount */ Hatena.Star.InnerCount = new Ten.Class({ initialize: function(count, e) { this.count = count; this.entry = e; var c = document.createElement('span'); c.setAttribute('class', 'hatena-star-inner-count'); Ten.Style.applyStyle(c, Hatena.Star.InnerCount.style); c.style.cursor = 'pointer'; c.innerHTML = count; new Ten.Observer(c,'onclick',this,'showInnerStars'); this.container = c; return c; }, style: { color: '#f4b128', fontWeight: 'bold', fontSize: '80%', fontFamily: '"arial", sans-serif', margin: '0 2px' } },{ showInnerStars: function() { var url = Hatena.Star.BaseURL + 'entry.json?uri=' + encodeURIComponent(this.entry.uri); new Ten.JSONP(url, this, 'receiveStarEntry'); }, receiveStarEntry: function(res) { var se = res.entries[0]; var e = this.entry; if (encodeURIComponent(se.uri) != encodeURIComponent(e.uri)) return; e.flushStars(); e.bindStarEntry(se); e.addAddButton(); e.showStars(); } }); /* Hatena.Star.Comment */ Hatena.Star.Comment = new Ten.Class({ initialize: function(args) { this.name = args.name; this.body = args.body; } },{ asElement: function() { var div = document.createElement('div'); with (div.style) { margin = '0px 0'; padding = '5px 0'; borderBottom = '1px solid #ddd'; } var ico = Hatena.User.getProfileIcon(this.name); div.appendChild(ico); var span = document.createElement('span'); with(span.style) { fontSize = '90%'; } span.innerHTML = this.body; div.appendChild(span); return div; } }); /* Hatena.Star.NameScreen */ Hatena.Star.NameScreen = new Ten.Class({ base: [Ten.SubWindow], style: { padding: '2px', textAlign: 'center' }, containerStyle: { margin: 0, padding: 0 }, handleStyle: null, showScreen: false, closeButton: null, draggable: false },{ showName: function(name, pos) { this.container.innerHTML = ''; this.container.appendChild(Hatena.User.getProfileIcon(name)); this.container.appendChild(document.createTextNode(name)); this.show(pos); } }); /* Hatena.Star.AlertScreen */ Hatena.Star.AlertScreen = new Ten.Class({ base: [Ten.SubWindow], style: { padding: '2px', textAlign: 'center', borderRadius: '6px', MozBorderRadius: '6px', width: '240px', height: '120px' }, handleStyle: { position: 'absolute', top: '0px', left: '0px', backgroundColor: '#f3f3f3', borderBottom: '1px solid #bbb', width: '100%', height: '30px', borderRadius: '6px 6px 0 0', MozBorderRadius: '6px 6px 0 0' } },{ showAlert: function(msg, pos) { this.container.innerHTML = msg; var win = Ten.Geometry.getWindowSize(); var scr = Ten.Geometry.getScroll(); var w = parseInt(this.constructor.style.width) + 20; if (pos.x + w > scr.x + win.w) pos.x = win.w + scr.x - w; this.show(pos); } }); /* Hatena.Star.CommentScreen */ Hatena.Star.CommentScreen = new Ten.Class({ base: [Ten.SubWindow], initialize: function() { var self = this.constructor.SUPER.call(this); if (!self.commentsContainer) self.addCommentsContainer(); return self; }, style: { width: '280px', height: '280px', overflowY: 'auto', padding: '2px', textAlign: 'center', borderRadius: '6px', MozBorderRadius: '6px' }, handleStyle: { position: 'absolute', top: '0px', left: '0px', backgroundColor: '#f3f3f3', borderBottom: '1px solid #bbb', width: '100%', height: '30px', borderRadius: '6px 6px 0 0', MozBorderRadius: '6px 6px 0 0' }, containerStyle: { margin: '32px 0 0 0', textAlign: 'left', padding: '0 10px' }, getLoadImage: function() { var img = document.createElement('img'); img.src = Hatena.Star.BaseURL + 'images/load.gif'; img.setAttribute('alt', 'Loading'); with (img.style) { verticalAlign = 'middle'; margin = '0 2px'; } return img; } },{ addCommentsContainer: function() { var div = document.createElement('div'); with (div.style) { marginTop = '-3px'; } this.container.appendChild(div); this.commentsContainer = div; }, showComments: function(e, pos) { var comments = e.comments; if (!comments) comments = []; this.commentsContainer.innerHTML = ''; for (var i=0; i<comments.length; i++) { this.commentsContainer.appendChild(comments[i].asElement()); } if (e.starEntry && !e.can_comment) { this.hideCommentForm(); } else { this.addCommentForm(); } var win = Ten.Geometry.getWindowSize(); var scr = Ten.Geometry.getScroll(); var w = parseInt(this.constructor.style.width) + 20; if (pos.x + w > scr.x + win.w) pos.x = win.w + scr.x - w; this.show(pos); }, bindEntry: function(e) { this.entry = e; }, sendComment: function(e) { if (!e.isKey('enter')) return; var body = this.commentInput.value; if (!body) return; this.commentInput.disabled = 'true'; this.showLoadImage(); var url = Hatena.Star.BaseURL + 'comment.add.json?body=' + encodeURIComponent(body) + '&uri=' + encodeURIComponent(this.entry.uri) + '&title=' + encodeURIComponent(this.entry.title); new Ten.JSONP(url, this, 'receiveResult'); }, receiveResult: function(args) { if (!args.name || !args.body) return; this.commentInput.value = ''; this.commentInput.disabled = ''; this.hideLoadImage(); var com = new Hatena.Star.Comment(args); this.entry.addComment(com); this.commentsContainer.appendChild(com.asElement()); }, showLoadImage: function() { if (!this.loadImage) return; this.loadImage.style.display = 'inline'; }, hideLoadImage: function() { if (!this.loadImage) return; this.loadImage.style.display = 'none'; }, hideCommentForm: function() { if (!this.commentForm) return; this.commentForm.style.display = 'none'; }, addCommentForm: function() { if (this.commentForm) { this.commentForm.style.display = 'block'; return; } var form = document.createElement('div'); this.container.appendChild(form); this.commentForm = form; with (form.style) { margin = '0px 0'; padding = '5px 0'; // borderTop = '1px solid #ddd'; } //if (Hatena.Visitor) { // form.appendChild(Hatena.Visitor.profileIcon()); //} else { // form.appendChild(Hatena.User.getProfileIcon()); //} var input = document.createElement('input'); input.type = 'text'; with (input.style) { width = '215px'; border = '1px solid #bbb'; padding = '3px'; } form.appendChild(input); this.commentInput = input; var img = this.constructor.getLoadImage(); this.loadImage = img; this.hideLoadImage(); form.appendChild(img); new Ten.Observer(input,'onkeypress',this,'sendComment'); } }); /* Hatena.Star.EntryLoader */ Hatena.Star.EntryLoader = new Ten.Class({ initialize: function() { var entries = Hatena.Star.EntryLoader.loadEntries(); this.entries = []; for (var i = 0; i < entries.length; i++) { var e = new Hatena.Star.Entry(entries[i]); e.showButtons(); this.entries.push(e); } this.getStarEntries(); }, createStarContainer: function() { var sc = document.createElement('span'); sc.setAttribute('class', 'hatena-star-star-container'); sc.style.marginLeft = '1px'; return sc; }, createCommentContainer: function() { var cc = document.createElement('span'); cc.setAttribute('class', 'hatena-star-comment-container'); cc.style.marginLeft = '1px'; return cc; }, scrapeTitle: function(node) { var rval = []; (function (node) { if (node.tagName == 'SPAN' && (node.className == 'sanchor' || node.className == 'timestamp')) { return; } else if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) { return; } var cn = node.childNodes; if (cn) { for (var i = 0; i < cn.length; i++) { arguments.callee.call(this, cn[i]); } } var nodeValue = node.nodeValue; if (typeof(nodeValue) == 'string') { rval.push(nodeValue); } })(node); return rval.join(''); }, headerTagAndClassName: ['h3',null], getHeaders: function() { var t = Hatena.Star.EntryLoader.headerTagAndClassName; return Ten.DOM.getElementsByTagAndClassName(t[0],t[1],document); }, loadEntries: function() { var entries = []; //var headers = document.getElementsByTagName('h3'); var c = Hatena.Star.EntryLoader; var headers = c.getHeaders(); for (var i = 0; i < headers.length; i++) { var header = headers[i]; var a = header.getElementsByTagName('a')[0]; if (!a) continue; var uri = a.href; var title = ''; // Ten.DOM.removeEmptyTextNodes(header); var cns = header.childNodes; title = c.scrapeTitle(header); var cc = c.createCommentContainer(); header.appendChild(cc); var sc = c.createStarContainer(); header.appendChild(sc); entries.push({ uri: uri, title: title, star_container: sc, comment_container: cc }); } return entries; } },{ getStarEntries: function() { var url = Hatena.Star.BaseURL + 'entries.json?'; for (var i = 0; i < this.entries.length; i++) { if (url.length > Ten.JSONP.MaxBytes) { new Ten.JSONP(url, this, 'receiveStarEntries'); url = Hatena.Star.BaseURL + 'entries.json?'; } url += 'uri=' + encodeURIComponent(this.entries[i].uri) + '&'; } new Ten.JSONP(url, this, 'receiveStarEntries'); }, receiveStarEntries: function(res) { var entries = res.entries; if (!entries) entries = []; for (var i = 0; i < this.entries.length; i++) { var e = this.entries[i]; for (var j = 0; j < entries.length; j++) { var se = entries[j]; if (!se.uri) continue; if (encodeURIComponent(se.uri) == encodeURIComponent(e.uri)) { e.bindStarEntry(se); entries.splice(j,1); break; } } if (typeof(e.can_comment) == 'undefined') { e.setCanComment(res.can_comment); } e.showStars(); e.showCommentButton(); } } }); /* Hatena.Star.WindowObserver */ Hatena.Star.WindowObserver = new Ten.Class({ initialize: funct
>> kn1967
Unix系に関しては必ずしもファイルタイプを拡張子で判別しません。たしかにKDEやGnome, Firefoxは拡張子で判別しているふしがありますが、それはあくまでもアプリケーションの機能です。OSの機能としては、先頭のマジックナンバーで判断するので、たとえPerlのスクリプトをhogehoge.cという拡張子で保存したとしても、実行権限さえあれば ./hogehoge.c で実行することができます。
>> kira2007(質問主)
「HTMLソースが混じったperl」って何のことでしょうか?
もしかしてshtmlのことですか?