はてなキーワード: objectとは
修正:いい加減&が変換されるのを何とかしてほしい
解説:Hatena::Bookmark::24H(http://hatebu24h.ashitano.in/)に、トップエントリの獲得したブックマーク数の推移のチャートを加えます。
// ==UserScript== // @name chart of Hatena::Bookmark::24H // @namespace http://anond.hatelabo.jp/ // @include http://hatebu24h.ashitano.in/* // ==/UserScript== var url = unescape("http://chart.apis.google.com/chart?chs=160x60%26cht=ls%26chd=t:"); url = url + $X("//div[@class='clocktxt']", Array).map(function(s){return s.firstChild.nodeValue}).join(","); //var id = $X("//h3/a/@href")[0].nodeValue; //url = url + $X("//div[@class='entrytitle' or @class='entrytitle2'][.//a[@href='"+id+"']]/../preceding-sibling::div[1]", Array).map(function(s){return s.textContent.match(/\d+/)}).join(","); var before = makeElements({ nodeName: "div", className: "sidebox", childNodes: [{ nodeName: "div", className: "sidetitle", innerHTML: "Recent top entry chart" },{ nodeName: "div", className: "sidetitle", childNodes: { nodeName: "img", src: url } }] }); var after = $X("//div[@class='sidebox']", Array)[0]; after.parentNode.insertBefore(before, after); // util // var 0.01 function makeElements(obj) { if (typeof obj != "object") return document.createTextNode(obj); if (obj instanceof Array) return obj.map(makeElements); var node = document.createElement(obj.nodeName); delete obj.nodeName; if (obj.childNodes) { [].concat(makeElements(obj.childNodes)).forEach(node.appendChild, node); delete obj.childNodes; } function extend(dst, src) { for (var i in src) { if (typeof src[i] == "object" && dst[i] && typeof dst[i] == "object") extend(dst[i], src[i]); else node[i]=obj[i]; } } extend(node, obj); return node; } // by http://lowreal.net/blog/2007/11/17/1 // $X(exp); // $X(exp, context); // $X(exp, type); // $X(exp, context, type); function $X (exp, context, type /* want type */) { if (typeof context == "function") { type = context; context = null; } if (!context) context = document; var exp = (context.ownerDocument || context).createExpression(exp, function (prefix) { var o = document.createNSResolver(context).lookupNamespaceURI(prefix); if (o) return o; return (document.contentType == "application/xhtml+xml") ? "http://www.w3.org/1999/xhtml" : ""; }); switch (type) { case String: return exp.evaluate( context, XPathResult.STRING_TYPE, null ).stringValue; case Number: return exp.evaluate( context, XPathResult.NUMBER_TYPE, null ).numberValue; case Boolean: return exp.evaluate( context, XPathResult.BOOLEAN_TYPE, null ).booleanValue; case Array: var result = exp.evaluate( context, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ); var ret = []; for (var i = 0, len = result.snapshotLength; i < len; i++) { ret.push(result.snapshotItem(i)); } return ret; case undefined: var result = exp.evaluate(context, XPathResult.ANY_TYPE, null); switch (result.resultType) { case XPathResult.STRING_TYPE : return result.stringValue; case XPathResult.NUMBER_TYPE : return result.numberValue; case XPathResult.BOOLEAN_TYPE: return result.booleanValue; case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: { // not ensure the order. var ret = []; var i = null; while (i = result.iterateNext()) { ret.push(i); } return ret; } } return null; default: throw(TypeError("$X: specified type is not valid type.")); } }
jboss2.4.3で、entitybeanに対してremoveメソッドを呼んだ場合、 <<
なぜかbeanのキャッシュにobjectが残存していて、さいど同じprimarykeyで
create後removeすると、remove内でDBへのconnectionを解放している
場合にSQLExceptionが発生する。やはりjbossのエラーだそうな。
一番最初のremoveでconnection.close()を呼んだままになってるから
当然。SunのEJB仕様によれば、ejbRemoveとejbPassivateはともに
beanをプール状態に移行するもので(つまり同じ動作)かつejbRemoveでは
日本語じゃねえ。
いまさらなんだけど。
javascript:t=document.title;l=location.href;c=prompt('make a memo:\n'+t+'\n'+l,' ');if(typeof c != 'object')window.open('http://anond.hatelabo.jp/<ここを自分のidにする>/edit?mode=confirm&title='+escape(l)+'&body=:'+escape(t)+':'+escape(c));undefined;
★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
_________________ここから下は古い情報▼__________________________________________________
今、自分のブログをスクラッチしているので、こちらで。→2008/9/28 スクラッチ完了!BLACK-OUT.CSS公式ページ
作りました
要は、LynxのようなシンプルWebに世界がなればいいのになと思っている方。
そして、どんなサイトでも目線は左右に動かしたくない!スクロールは上下だけで済ませたい!
と、強く考えておられる方むけの情報です。
私はテキストブラウザのLynxを時々使っているのですが、これでサイトを見るとシンプルに見れるのですごく良いんですよね。
ただ、LynxはFlashとか画像が見れないし、マウスが使えないのはいざって時にちょっと不便。
で、Firefoxをテキストブラウザ化できないかなあと、ふと思いまして、思いつきで作ってしまいました。
私めもwebデザイナーやっとるんですが、上記のように、昨今のwebデザインなんて普段はなくていいって思っている奴でして。
仕事じゃ3カラムのサイトとか作りますが自分はそんなん好きじゃないです。色がサイトごとに違うってのも理解できない。
必要なのは情報であってデザイナーのデザインなんてどうでもいいんですよ。
そんな訳で、どんなサイトでもテキストブラウザ状態で閲覧できるFirefox用の拡張cssを作りました(やっつけだけど)。
ただ、ニュースサイトで画像が見れないと困る時もあるので、普段は小さなサムネイルで、カーソルを合わせた時だけ大きく表示されるようにしています。
@このcssはコンセプト実証モデルです。思いつきで作ってるのでちょっと問題もあります。フィードバックとか意見など頂けると嬉しいかも。
@将来的には、グリモンでjsも組み合わせてもっとコンソールのような感覚でブラウジングできるようにしたい
@(参考用)私のよく見るサイト・・・ニコ動、wikipedia、スラッシュドットジャパン、2nn.jp(2ch)、mixi、はてなでホッテントリに上がっているブログ各種
ちなみに、こんなん使うな、既にこんないいのあるわいってのをご存知の方は教えてくれると嬉しいです。
それなりに探したのだけど、見当たらなくて・・・だから自作したので。
/* * ---------------------------- * black-out.css * author zamamin.com * build 2008.8.09 15:03 * version 0.0.31 * fix @namespaceを書いてなかったので追加 * ---------------------------- * */ @namespace url(http://www.w3.org/1999/xhtml); /* 全てのエレメントをリセット */ body,body * { background-image:none !important; background-color:#000 !important; border-color:#333 !important; text-decoration:none !important; color:#aaa !important; /*<- テキスト色 */ font-size:16px !important; /*<- 文字サイズ */ font-weight:normal !important; padding:0.15em !important; margin:0 !important; line-height:1.25em !important; text-align:left !important; text-indent:0 !important; font-family:Arial,Helvetica,Verdana,'ヒラギノ角ゴPro W3','Hiragino Kaku Gothic Pro',Osaka,'メイリオ',Meiryo,'MS Pゴシック',sans-serif !important; float:none !important; clear:both !important; position:relative !important; width:auto !important; height:auto !important; } body { background-color:#000 !important; padding:0.5em !important; } body * p, body * div, body * h1, body * h2, body * h3, body * h4, body * h5, body * h6{ margin-bottom:0.3em !important; float:left !important; clear:both !important; } /* リンク色 */ body * a, body * a *{ color:#a50 !important; } /* アクセス済みのリンク色 */ body * a:visited{ color:#a50 !important; } /* カーソルを合わせた時のリンク色 */ body * a:hover, body * a:hover *{ color:#0aa !important; background-color:#609 !important; } /* 画像は普段は小さくサムネイル表示。鬱陶しいので薄く表示 */ body * img{ opacity:0.3 !important; height:15px !important; width:15px !important; } /* 画像はマウスカーソルもっていけば原寸サイズになる */ body * img:hover{ opacity:0.9 !important; height:auto !important; width:auto !important; } button, input, select, option, textarea{ color:#f00 !important; padding:0.05em !important; height:auto !important; } /* テーブルのスタイル */ table{ border:none; } table td, table th{ border:none; border-right:1px dashed #999 !important; border-bottom:1px dashed #999 !important; } /* for 2ch(暫定) */ body * dt{ font-weight:bold !important; } /* 二コ動 */ embed#flvplayer{ height:540px !important; width:952px !important; }
サーバーサイドでマジメに作ったら逮捕されるんだろうか…?けーさつこわいから悪用とかしないでね><
ところで2chのどっかの板の名前欄って人名と地名がランダム表示されるけど、どうやってリストを作成してるんだろ?
<html><head><title>反抗予告ジェネレータ</title><script type="text/javascript"><!-- var safe_mode = 1; var date, place, object, action; date = get_date(); object = get_object(); action = get_action(); httpRequest("http://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC%E3%81%AE%E5%A4%A7%E5%AD%A6%E4%B8%80%E8%A6%A7"); function get_date() { var now = new Date(); now.setTime(now.getTime() + Math.floor(Math.random()*1000*60*60*24*30)); if (safe_mode != 0) { now.setTime(now.getTime() + 1000*60*60*24*(365*3+366)/4*100); } return now.getYear()+"年"+(now.getMonth()+1)+"月"+now.getDate()+"日"+now.getHours()+"時"+now.getMinutes()+"分"+now.getSeconds()+"秒"; } function get_object() { var b = ["小女子", "増田", "ひろゆき", "ぬこ"]; return b[Math.floor(Math.random()*b.length)]; } function get_action() { var b = ["投", "SATSUGAI", "なでなで", "もふもふ"]; return b[Math.floor(Math.random()*b.length)]; } function httpRequest(target_url) { try { if(window.XMLHttpRequest) { httpObj = new XMLHttpRequest(); } else if(window.ActiveXObject) { httpObj = new ActiveXObject("Microsoft.XMLHTTP"); } else { return; } } catch(e) { return; } httpObj.open("GET", target_url, true); httpObj.onreadystatechange = DataRead; httpObj.send(""); return; } function DataRead() { if (httpObj.readyState == 4 && httpObj.status == 200) { var res = httpObj.responseText; var b = new Array(); b = res.match(/>([亜-熙]+)大学/g); place = b[Math.floor(Math.random()*b.length-1)].replace(">",""); if (safe_mode != 0) { place = place.replace("大学", "○○"); } document.body.innerText = date+"に"+place+"あたりで"+object+"を"+action+"します…!"; } } // --></script></head><body style="color:red; background-color:black; font-size:30px; text-align:center;"></body></html>
javascriptでスーパークラスのメソッドを簡単に呼び出したかった。それだけだった。
var Class = inherit(SuperClass, {hoge: ...});
作ったクラスはprototypeに、第二引数のオブジェクトがコピーされたスーパークラスのインスタンスを持つ。
第一引数がnullだと、スーパークラスにObjectを用いる。つまり、
var Class = inherit(null, {hoge: ...});
は
var Class = inherit(Object, {hoge: ...});
と同等となる。
また、第一引数が"prototype"をメンバに持たない普通のオブジェクト、つまり、
var Class = inherit({hoge: ...});
だと
var Class = inherit(Object, {hoge: ...});
と同等となる。
var obj = new Class({hoge: ...});
でインスタンスを作ると、引数のオブジェクトのコピーを持つオブジェクトとなる。
また、メソッド"initialize"が自動的に実行される。
ただし、コンストラクタに引数を渡さなかった場合は、initializeは実行されない。
this.superapply(arguments);
としてスーパークラスのメソッドを呼べる。第一引数は呼び出すメソッドの引数の配列とする。
このとき、呼び出し側のメソッドはコンストラクタやinheritでオーバーライドしたメソッドでなくてはならない。これは呼び出し側のメソッド名を記録する必要があるためである。
そうでない場合は第二引数にメソッド名を渡す必要がある。
var obj = new Class({}); obj.foo = function(){ this.superapply(arguments); // X this.superapply(arguments, "foo"); // O };
<html><head> <script type="text/javascript"> function inherit(superclass, override) { if (!superclass) superclass = Object; if (! "prototype" in superclass) { override = superclass; superclass = Object; } var that; var func; function superapply(arg, name) { var prev = {that: that, func: func}; try { var my = this.superapply; if (!arg) arg = []; if (!name) name = arguments.callee.caller.caller.methodName; if (that && func && (!name || name == func.methodName)) { that = that.superapply.obj; name = func.methodName; } else if (name) { that = my.obj; func = arguments.callee.caller.caller; func.methodName = name; } else { throw new Error("methodName is null"); } var result; if (func === that[name]) { result = this.superapply(arg, name); } else { func = that[name]; func.methodName = name; result = func.apply(this, arg); } } finally { that = prev.that; func = prev.func; } return result; }; var prototype = new superclass(); prototype.superapply = function(){superapply.apply(this, arguments)}; prototype.superapply.obj = superclass.prototype; if (override) for (var i in override) { prototype[i] = override[i]; if (typeof override[i] == "function") prototype[i].methodName = i; } var subclass = function(obj) { this.superapply = function(){superapply.apply(this, arguments)}; this.superapply.obj = prototype; if (obj) { for (var i in obj) { this[i] = obj[i]; if (typeof obj[i] == "function") this[i].methodName = i; } this.initialize(); } }; subclass.prototype = prototype; subclass.prototype.constructor = subclass; return subclass; } var C1 = inherit(Object, { fn: "C1", initialize: function(){ alert("C1.initialize"); this.second(this.fn); }, second: function(a){ alert("C1.second: "+a); } }); var C2 = inherit(C1, { fn: "C2", initialize: function(){ alert("C2.initialize"); this.superapply(); // }, //second: // function(a){ // alert("C2.second: "+a); // this.superapply([a]); } }); var C3 = new C2({ fn: "C3", //initialize: // function(){ // alert("C3.initialize"); // this.superapply(); // }, second: function(a){ alert("C3.second: "+a); this.superapply([a]); } }); </script> </head><body> </body><html>
methodNameなんとかならんもんか。
最近Perl界隈ではMoose、MooseってなんかMooseってのが流行ってるらしい。
自分自身のブログでは、さもずっと前からMoose知ってたかのように振舞うために、増田で先に放出しておく。てへへ。
プログラマ層が限りなく低い増田にこんなこと書いてもだれも見てくれない気はするけど。
初めてのMoose - Mooseのすすめ - はてな#hide-k
meta object protocol について考えてみる - TokuLog 改めChumbyとどきました日記
YappoLogs: Moose のコードを探索して理解を深めた
Mooseってのは結局のところClass::MOPのラッパーみたいなもんだと。
で、Class::MOPってのは何だ?ってことだけど、メタなんとかプログラミング?え?プロトコル?まーどっちでもいい。
よくよく読んでいくとメタなんとかとか大層な名前が付いてるけど、結局のところPerlのpackageそのものの操作をオブジェクティブ扱えるようにしたものみたいだ。
つまりだな、例えばpackageに対して動的に(静的ではなく!)メソッドを追加したい場合、今までなら
package Foo; **Foo::method = sub { return 'hoge'; }; print Foo->method;
のように型グロブに関数のリファレンスを突っ込むということをしなければなかったが
use Class::MOP; my $class = Class::MOP::Class->create('Foo'); $class->add_method('method',sub { return 'hoge'; }); print Foo->method;
みたいな感じでかっこよく追加できるってわけさ。ま、これはほんの一例だけどな。(他にもメソッドを削除したりフックしたり色々できる。その辺は今回省略。)
本来なら「package Foo」とするところを「my $class = Class::MOP::Class->create('Foo');」と書ける。
これの何が良いのかというと、$classというオブジェクト経由でFooパッケージを色々操作できるところにつきる。
型グロブを使用したり「no (warnings|strict)」をしたりパッケージを操作する処理っていうのはPerlのキチャナイ構文が多かったのだが、Class::MOPのおかげでスッキリ綺麗に書けるようになったってこった。
で、次にMooseだが、これは結局のところClass::MOPのパッケージ管理の部分に+αしただけのラッパーだ。
でもその+αってのが結構凄かったりする。
もうこの辺の話はさんざん既出だが、例えばhasという関数を使ってアクセサや型定義が出来たり
package Foo; use Moose; has 'method' => ( is => 'rw', isa => 'Int' , default => '10' ); my $obj = Foo->new; print $obj->method; # 10 $obj->method(50); print $obj->method; # 50 $obj->method('hoge') # Int型じゃないのでエラー
Moose::Roleを使ってRubyのMixinみたいなことができたりする。
でも実はこれらの処理ってのは本当は別に凄くもなんとも無い。
アクセサ生成なんてClass::Accessorがあるし、関数の引数の型チェックなんてのもParams::Validate等昔から存在してるし、Mixinに関してはもともとPerlは多重継承できるので最初からできるし。
じゃあなんでみんなMoose、Moose言ってるのかっていうと、それはやはりClass::MOPの存在が大きいであろう。
綺麗且つ柔軟にパッケージの操作が出来るClass::MOPが土台にあって、今まで別々の役割として存在してきたモジュール達を統合し、よりわかりやすく、より柔軟に、そしてより強力なPerlのオブジェクト指向を構築できるようにした。それがMooseなのだ。
・・・しかし、小生。
Mooseについて調べていくうちに一つ残念に思ったことがある。
オブジェクトにメソッドを追加する機構がないのだ。
オブジェクトにメソッドを追加する、だ。パッケージにではなく、オブジェクトに、だ。
具体例をあげる。
package Foo; use Moose; my $obj = Foo->new; $obj->meta->add_method('hoge', sub { return 'hoge' }); print $obj->hoge; # hoge
ちなみに$obj->metaというのはFooパッケージを管理するClass::MOPへのアクセサだ。
ということは上記の処理はFooに対してhogeというメソッドを追加していることになる。
では次の例。
package Foo; use Moose; my $obj = Foo->new; $obj->meta->add_method('hoge', sub { return 'hoge' }); print $obj->hoge; # hoge my $obj_2 = Foo->new; print $obj_2->hoge; # hoge
$obj_2->hogeが呼べてしまうわけだ。
$obj->metaは結局のところFooパッケージなのだから、そこにメソッドを追加しているので当然の結果である。
$objだけにメソッドを追加することは、Mooseではできないのだ。
非常に残念である。ああ、残念だ。
・・・しかし、小生。
これでもプログラマの端くれである。こんなことでめげていてはMooserを名乗れないのである。(あ、MooserってのはMoose使いの人の俗称ね。今僕が考えたの)
なのでオブジェクトにメソッドを追加できるように拡張して見せよう。
package Foo; use Moose; use Class::Object; my $class_object = Class::Object->can('new'); override new => sub { ref($class_object->(shift))->SUPER::new(@_) }; my $obj = Foo->new; $obj->meta->add_method('hoge', sub { return 'hoge' }); print $obj->hoge; # hoge my $obj_2 = Foo->new; print $obj_2->hoge; # エラー
たった3行追加するだけで実現できる。さすがMoose。
ただし、Class::Objectを利用しているのでFoo->newで返ってくるパッケージがFoo::0といったようにFooではなくなってしまっているのでrefとかでパッケージ名の比較ができなくなってしまう問題が発生する。
でもこれも継承順をいじったりと本気で頑張れば、表向きに見せるパッケージ名をFooすることも可能だろう。
その添削の役目はどこかのハッカーに任せるとして、今日のところはこの辺で終了としたい。
Moooooooooooooose!と叫ぶのが流行ってるみたいなので、もっとも長くMooooooooooooooose!と叫んだ最初の男となるべく下記の処理を残しておく。
length q chdir uc and print chr ord uc q rmdir and do { print chr ord q xor x while $a++ < 0xffffffff } or print chr ord qw q sin q and print chr ord q ne sin and print chr hex length q q shift shmread bless q;
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="320" height="205" id="flvplayer" align="middle"> <param name="allowScriptAccess" value="sameDomain" /> <param name="movie" value="http://g.hatena.ne.jp/tools/flvplayer.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#ffffff" /> <param name="FlashVars" value="moviePath=http://www.youtube.com/watch?v=eMrC8tt1UCU" /> <embed src="http://g.hatena.ne.jp/tools/flvplayer.swf" FlashVars="moviePath=http://www.youtube.com/watch?v=eMrC8tt1UCU" quality="high" bgcolor="#ffffff" width="320" height="205" name="flvplayer" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> </object>
Python2.5のときは、新スタイルクラスのインスタンスは辞書のキーとして必ず使用できたけど、Python 2.6ではそういうわけじゃなくなってるぽい。という話。
class TestClass(object): def __init__(self, i_name): self._name = i_name def __eq__(self, i_other): if not isinstance(i_other, TestClass): return False return self._name == i_other._name print 'object.__hash__ = ' + str(object.__hash__) print 'TestClass.__hash__ = ' +str(TestClass.__hash__)
上記のようなコードを実行したら、Python 2.5とPython 2.6で結果が違いました。
Python 2.5の場合の結果。
object.__hash__ = <slot wrapper '__hash__' of 'object' objects> TestClass.__hash__ = <slot wrapper '__hash__' of 'object' objects>
Python 2.6の場合の結果。
object.__hash__ = <slot wrapper '__hash__' of 'object' objects> TestClass.__hash__ = None
Python 2.6だと、objectクラスを継承すると、__hash__がNoneになっちゃってる。このままだと辞書のキーとして使えないね。objectを継承したクラスで__hash__を実装すれば、大丈夫みたい。
「ハッシュ値の計算方法 (2)」というページも参考になりそう。
唐突に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 && $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
http://anond.hatelabo.jp/20071030034313 の二番煎じ
あまりのアホさに、作ってて気が狂いかけた
方針
using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.IO; using System.Reflection; using Microsoft.CSharp; delegate void ConvertTemplateDelegate(TextWriter tw, Dictionary<object, object> args); static class TemplateGenerator { public static ConvertTemplateDelegate Generate(string code) { CompilerParameters param = new CompilerParameters(); param.GenerateInMemory = true; param.ReferencedAssemblies.Add("System.Web.dll"); CompilerResults rs = new CSharpCodeProvider().CompileAssemblyFromSource(param, ParseTemplate(code)); if (0 < rs.Errors.Count) { StringWriter sw = new StringWriter(); sw.WriteLine("Compile Error..."); foreach (CompilerError err in rs.Errors) sw.WriteLine(err.ToString()); throw new Exception(sw.ToString()); } return (ConvertTemplateDelegate) Delegate.CreateDelegate(typeof(ConvertTemplateDelegate), rs.CompiledAssembly.GetType("Template", true).GetMethod("Convert")); } private static string ParseTemplate(string code) { using (StringWriter sw = new StringWriter()) { sw.WriteLine("using System; using System.Collections.Generic; using System.IO; using System.Web;"); sw.WriteLine("public static class Template {"); sw.WriteLine("public static void Convert(TextWriter tw, Dictionary<object, object> args) {"); int index = 0; while (0 <= index && index < code.Length) { int i = code.IndexOf("<%", index); sw.WriteLine("tw.Write(\"{0}\");", EscapeString(i < 0 ? code.Substring(index) : code.Substring(index, i - index))); if (0 <= i) { i += 2; int i2 = code.IndexOf("%>", i); if (0 <= i2) { string cc = code.Substring(i, i2 - i); if (cc.StartsWith("=")) sw.WriteLine("tw.Write(HttpUtility.HtmlEncode(\"\"+({0})));", cc.Substring(1)); else sw.WriteLine(cc); i = i2 + 2; } } index = i; } sw.WriteLine("}}"); return sw.ToString(); } } private static string EscapeString(string code) { return code.Replace("\\", "\\e").Replace("\"", "\\\"").Replace("\t", "\\t").Replace("\n", "\\n").Replace("\r", "\\r").Replace("\\e", "\\\\"); } }
サンプル C# コード。ためしにテンプレートから Xml 生成して、標準出力してみる。
class Program { static void Main(string[] args) { ConvertTemplateDelegate func = TemplateGenerator.Generate(TemplateEngine.Resource1.template); using (StringWriter sw = new StringWriter()) { Dictionary<object, object> arg = new Dictionary<object, object>(); arg["title"] = "template sample"; arg["data"] = new string[] { "foo", "fooo", "<strong>foooooooooo!</strong>" }; func(sw, arg); Console.WriteLine(sw); } } }
サンプルテンプレート
<?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"> <head> <title><%= args["title"] %></title> </head> <body> <h1><%= args["title"] %></h1> <table> <% string[] data = (string[]) args["data"]; %> <% for(int i = 0; i < data.Length; i++) { %> <tr bgcolor="<%= i % 2 == 0 ? "#FFCCCC" : "#CCCCFF" %>"> <td><%= i %></td> <td><%= data[i] %></td> </tr> <% } %> </table> </body> </html>
出力例
<?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"> <head> <title>template sample</title> </head> <body> <h1>template sample</h1> <table> <tr bgcolor="#FFCCCC"> <td>0</td> <td>foo</td> </tr> <tr bgcolor="#CCCCFF"> <td>1</td> <td>fooo</td> </tr> <tr bgcolor="#FFCCCC"> <td>2</td> <td><strong>foooooooooo!</strong></td> </tr> </table> </body> </html>
CodeDom 使って動的コンパイル……って、このコードのままだとセキュリティ的に大問題な気がするな。
素直に ASP.NET 使ったほうが楽だと直感した。
あと EscapeString すっごく自信ない。たぶん修正が必要だと思うw
404 Blog Not Found:coders.each{|you| you.get(this) if you.langs[0] != 'ruby' } # - 書評 - 初めてのRuby
1章 ようこそ、Rubyのある生活へ
1.1 Rubyの特徴
1.1.1 オブジェクト指向言語
1.1.2 より良いPerl
ある研究によれば、生産性はそれぞれのプログラマでそれぞれ違う。
でも、あるプログラマに着目すれば、
そのプログラマが時間あたりに書けるコードの行数は、プログラミング言語によらず決まっている、
たとえば一年に50,000行なのだそうだ。
行数が決まっていたら、
どの言語で一番多くのことを達成できる?
そう、Rubyだよね。
例えば C のプログラムより 50 倍遅くなったとして、実行時間はどのくらい変わるだろうか?
もし C のプログラムが 0.01 秒で終わる としたら、
Ruby 版は 0.5 秒。あなたのプログラムは 0.49 秒速くす るために C で書く価値があるのか?
プログラムは開発の時間よりも保守の時間のほうがかかるというのはもはや常識だけども、
Ruby で書いてあれば例えば、
そういう点でも Ruby は非常にいい。
だいたい、スピードに対してごちゃごちゃ言うなら C じゃなくアセンブラで書けばいい。
それをなんで C で書いてるのかって言えば、
それはもちろん「コードがわかりやすい」とか、「早く書ける」って のが理由だろう。
そして、Ruby は C よりわかりやすいし速く書ける。
404 Blog Not Found:「PHPなめんな」と「(Perl|Python|Ruby)をなめんな」の違い
実行速度より実装速度(前編) - Object Station
<html><head><title>Hello JavaScript World!</title><style type="text/css"> <!-- .select { margin-left: 30px; padding: 0 2px; width: 6em; border: dotted 1px; } .select p { margin: 2px; } --> </style></head><body><script type="text/javascript"> <!-- // step 1 : output text document.write("Hello world!"); // step 2 : output html document.write("<br/><b>Hello javascript world!</b>"); // step 3 : manipulate DOM var p1 = document.createElement("p"); p1.appendChild(document.createTextNode("Hello DOM world!")); document.body.appendChild(p1); // step 3 : interactive, using function, event handler function solid() { this.style.borderStyle="solid"; } var p2 = document.createElement("p"); p2.appendChild(document.createTextNode("Hello interactive world!")); document.body.appendChild(p2); p2.addEventListener("click", solid, false); // not solid() // step 4 : using object, prototype, closure function P(str) { this.str = str; } P.prototype.regist = function(parent){ this.elem = document.createElement("p"); this.elem.appendChild(document.createTextNode(this.str)); parent.appendChild(this.elem); var self = this; this.elem.addEventListener("click", function(){self.act()}, false); // otherwise // this.elem.helloworld = this; // this.elem.addEventListener("click", function(){this.helloworld.act()}, false); // bad way // this.elem.addEventListener("click", this.act, false); // this.elem.addEventListener("click", function(){this.act()}, false); }; P.prototype.act = function(){}; var p3 = new P("Hello prototype world!"); p3.act = function(){ if (this.elem.style.borderStyle == ""){ this.elem.style.borderStyle = "solid"; } else { this.elem.style.borderStyle = ""; } }; p3.regist(document.body); // step 5 : inheritance function SELECT(parent, str) { this.str = str; this.regist(parent); } SELECT.prototype = new P(); SELECT.prototype.act = function(){ p4.elem.style.borderStyle = this.str; p4.div.style.display = "none"; } var p4 = new P("Hello world!"); p4.div = document.createElement("div"); p4.div.className = "select"; p4.div.style.display = "none"; p4.select = [ new SELECT(p4.div, "none"), new SELECT(p4.div, "dotted"), new SELECT(p4.div, "solid") ]; p4.act = function(){ p4.div.style.display = "block"; }; p4.regist(document.body); document.body.appendChild(p4.div); //--> </script></body></html>
(define str "Hello world") (let ((a 0)) (let1 b (with-input-from-string str (lambda () (port-fold (lambda (c b) (if (eqv? #\o c) (inc! a)) (+ 1 b)) 0 read-char))) (print a " " b)))
あるいはこう。
(use srfi-1) (define (times* e n) (map (lambda _ (e)) (iota n))) (define-macro (with-gensyms var . body) `(let ,(map (cut list <> '(gensym)) var) ,@body)) (define-macro (with-gensyms* var n . body) `(let ((,var (times* gensym ,n))) ,@body)) (define-macro (port-vfold proc seed reader) (with-gensyms (loop %proc v) (with-gensyms* pr (length seed) (with-gensyms* npr (length seed) `(let ((,%proc ,proc)) (let ,loop ((,v (,reader)) ,@(map list pr seed)) (if (eof-object? ,v) (values ,@pr) (receive ,npr (,%proc ,v ,@pr) (,loop (,reader) ,@npr))))))))) (receive (a b) (with-input-from-string "Hello world" (lambda () (port-vfold (lambda (c a b) (values (if (eqv? #\o c) (+ a 1) a) (+ 1 b))) (0 0) read-char))) (print a " " b))
文字列操作関数って高価じゃね?
/* 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
Object と Array をごっちゃにするのは、初学を助けても、そこから先が難しそうだけれども。
それ以上に Closer は無いな。Closure ね。『閉じるもの』ではなく、『中に包まれたもの』だから。
じゃ、OOはなんだろう。おおきいおっp
僕もだいすきおきいおっp
話を元に戻そう。OOはオブジェクト指向、object-orientedだよ。オブジェクト指向言語を扱った事がないなら、まずはオブジェクト指向について馴れる所からかも知れない。
20070629230000改定
20070702125800バグ発見:スクリプト中にある「&&」が、「&&」になっている。増田の仕様らしい。
20070827224900改定
// ==UserScript== // @name anond pickup // @namespace http://anond.hatelabo.jp/20070608230645 // @description pickup trackback tree top section at Hatelabo::AnonymousDiary // @include http://anond.hatelabo.jp/* // ==/UserScript== (function() { var threshold_bm = 1; var threshold_tb = 1; var ignoreList = { "/20070801172335": 33, "/20070806163721": 10, }; var firstPager_l = document.evaluate("//div[@class='pager-l']",document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue; function Hide(){} Hide.prototype.setup = function() { this.style = document.createElement("style"); this.style.id = "hide"; this.style.type = "text/css"; document.getElementsByTagName("head")[0].appendChild(this.style); var self = this; this.a = new Object(); this.a.visible = document.createElement("a"); this.a.visible.id = "visible"; this.a.visible.href = "#"; this.a.visible.innerHTML = "visible hide section"; // this.a.visible.setAttribute("onclick","document.getElementById('hide').innerHTML = 'div.hide {display: block}';document.getElementById('visible').style.display = 'none';document.getElementById('unvisible').style.display = 'inline';"); this.a.visible.addEventListener("click", function(){self.visible()}, false); firstPager_l.parentNode.insertBefore(this.a.visible, firstPager_l); this.a.unvisible = document.createElement("a"); this.a.unvisible.id = "unvisible"; this.a.unvisible.href = "#"; this.a.unvisible.innerHTML = "unvisible hide section"; // this.a.visible.setAttribute("onclick","document.getElementById('hide').innerHTML = 'div.hide {display: none}';document.getElementById('visible').style.display = 'inline';document.getElementById('unvisible').style.display = 'none';"); this.a.unvisible.addEventListener("click", function(){self.unvisible()}, false); firstPager_l.parentNode.insertBefore(this.a.unvisible, firstPager_l); if (GM_getValue("visible", 0)) { this.visible(); } else { this.unvisible(); } } Hide.prototype.visible = function() { this.style.innerHTML = "div.hide {display: block}"; this.a.visible.style.display = "none"; this.a.unvisible.style.display = "inline"; GM_setValue("visible", 1); } Hide.prototype.unvisible = function() { this.style.innerHTML = "div.hide {display: none}"; this.a.visible.style.display = "inline"; this.a.unvisible.style.display = "none"; GM_setValue("visible", 0); } Hide.prototype.append = function(section) { if (section.className.match(/hide/)) { return; } section.className += " hide"; } Hide.prototype.clear = function(section) { section.className = section.className.replace(/ hide/g, ""); } Hide.prototype.is = function(section) { return section.className.match(/hide/); } var hide = new Hide(); hide.setup(); var target = document.evaluate( "//div[@class='section' and child::*[not(@class='sectionfooter') and descendant::a[starts-with(@href,'http://anond.hatelabo.jp/2') or starts-with(@href,'/2') and not(child::span[@class='sanchor'])]]]", document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null); for (var i=0; i<target.snapshotLength; i++) { hide.append(target.snapshotItem(i)); } var tbs = document.evaluate( "//p[@class='sectionfooter']/a[2]", document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null); for (var i=0; i<tbs.snapshotLength; i++) { var tb = tbs.snapshotItem(i); if (tb.innerHTML == "\u30c8\u30e9\u30c3\u30af\u30d0\u30c3\u30af(0)") { // hide.append(tb.parentNode.parentNode); bookmark(tb, 0); } else if (! hide.is(tb.parentNode.parentNode)) { trackback(tb, 1); } else { bookmark(tb, 1); } } function trackback(tb, callback) { GM_xmlhttpRequest({ method: "GET", url: "http://anond.hatelabo.jp/" + tb.pathname.match(/\d{14}/), onload: function(result) { var link = result.responseText.match(/<a name="tb">(.|\s)*/)[0].match(/<li>\s*<a href="http:\/\/anond.hatelabo.jp\/\d{14}"/g); var n = link.length; for (var l in link) { var m = "/" + link[l].match(/\d{14}/); if (m in ignoreList) { n -= ignoreList[m]; } } if (n < threshold_tb) { tb.innerHTML = tb.innerHTML.replace(/\)$/, "/"+n+")"); if (callback) { bookmark(tb); } } else { tb.innerHTML = tb.innerHTML.replace(/\)$/, '/<span style="color: red;">'+n+"</span>)"); } } }); } function bookmark(tb, callback){ GM_xmlhttpRequest({ method: "GET", url: "http://b.hatena.ne.jp/entry/rss/http://anond.hatelabo.jp/" + tb.pathname.match(/\d{14}/), onload: function(result) { var r = result.responseText.match(/<rdf:li rdf:resource=/g); if (r && r.length >= threshold_bm){ hide.clear(tb.parentNode.parentNode); if (callback) { trackback(tb); } } else { hide.append(tb.parentNode.parentNode); } } }); } })();
今はスッキリしているのは古いやつ
/// ==UserScript== // @name anond pickup // @namespace http://anond.hatelabo.jp/20070608230645 // @description pickup trackback tree top section at Hatelabo::AnonymousDiary // @include http://anond.hatelabo.jp/*?page=* // ==/UserScript== (function() { var target = document.evaluate( "//div[@class='section' and child::*[not(@class='sectionfooter') and descendant::a[starts-with(@href,'http://anond.hatelabo.jp/2') or starts-with(@href,'/2') and not(child::span[@class='sanchor'])]]]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for(var i=0; i<target.snapshotLength; i++) { target.snapshotItem(i).style.display = "none"; } var trackback = document.evaluate( "//p[@class='sectionfooter']/a[2]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for(var i=0; i<trackback.snapshotLength; i++) { if (trackback.snapshotItem(i).innerHTML == "\u30c8\u30e9\u30c3\u30af\u30d0\u30c3\u30af(0)") { trackback.snapshotItem(i).parentNode.parentNode.style.display = "none"; } else if (trackback.snapshotItem(i).parentNode.parentNode.style.display != "none") { count(trackback.snapshotItem(i)); } } function count(tb) { GM_xmlhttpRequest({ method: "GET", url: "http://anond.hatelabo.jp/" + tb.getAttribute("href").match(/[0-9]{14}/), onload: function(result) { var n = result.responseText.replace(/\n/g,"").match(/<a name="tb">.*/)[0].match(/<li>/g).length; if (n < 10) { tb.innerHTML = tb.innerHTML.replace(/\)$/,"/"+n+")"); } else { tb.innerHTML = tb.innerHTML.replace(/\)$/,'/<span style="color: red;">'+n+"</span>)"); } } }); } })();
http://www.geekpage.jp/blog/?id=2006/12/13
プログラミング言語ヒエラルキーにおいて、上位が下位に対してどう見下してるのかを書いてみた。詳しくない言語も無理して調べながら書いてある。あと、他言語に理解の無い人みたいで生々しいかと思って、刺激的かつあまり真っ当でない内容ばっかにしてみたよ!((FORTRAN から Java に「GO TO も実装されてないんですか?」とかそういう、馬鹿にすることを目的とした偏狭で的外れな発言ってことだよ!))((ここにある中では、C# に多重継承が無いことを馬鹿にする C++ プログラマーが真っ当でない指摘のわかりやすい例かな))
みんなが普段どういう不当な見下しをしてるかも教えてね!
「C++ の難解な仕様と戦うぐらいなら C で関数ポインタを使ったオブジェクト指向の方がスマートだね」
「STL は糞」
「多重継承したくなったらどうするの?」
「CPAN 見たって C でコア部分を書いてるライブラリばっかじゃん」
「なんでわざわざ use strict なんて書かなきゃいけないの」
「Python って明示的に object を継承した場合としなかった場合で挙動が違うって本当なの?」
「ライブラリ環境が全然整備されてなくて最悪じゃん。C や C++ で書かれたライブラリをラップしてるだけのはずなのに機能が減りまくってるのも多いし」
「簡単な処理をコピペで実装してるだけだね」
「As とか書いてて混乱しない?」
「C# があるのにまだ使ってるんだ」
「冗長でわかりやすいですね(笑)」
「DIVISION の概念って本気で言ってるんですか?」
「記述がわかりづらいね」
「ペンタゴンで使われてるだけじゃん」
「ガベージコレクタが無い……?」(あるらしいです><)
「昔 Apple で使われてただけじゃん」
「Del…phi…?」
「コンパイルも実行も遅いらしいけど何に使うんですか?」
「処理も記述できないのに何言ってるの」
以下の二つに留意、つまり乱用禁止。
取説未満
// ==UserScript== // @name anond pickup of the day // @namespace http://anond.hatelabo.jp/ // @description pickup section of the day at Hatelabo::AnonymousDiary // @include http://anond.hatelabo.jp/2* // ==/UserScript== (function(){ var trackbackThreshold = 10; var ignoreList = { "/20070801172335": 33, "/20070806163721": 10, }; // only section of the day if (! location.pathname.match(/^\/\d{8}$/)) { return; } // regist ancher that kick main routine var a = document.createElement("a"); a.href = "#"; a.innerHTML = "pickup of the day"; a.addEventListener("click", grab, false); var firstPager_l = document.evaluate("//div[@class='pager-l']",document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue; firstPager_l.appendChild(a); function Outline() { this.outline = document.createElement("ul"); this.text = document.createElement("textarea"); this.text.style.overflow = "auto"; this.text.style.width = "100%"; this.text.style.height = "15em"; this.text.innerHTML = "</ul><\n><ul>\n"; this.list = new Array(); } Outline.prototype.setup = function() { var parent = document.getElementById("body"); parent.insertBefore(this.outline, parent.firstChild); parent.insertBefore(this.text, parent.firstChild); } Outline.prototype.append = function(section) { var h3 = section.getElementsByTagName("h3")[0]; var sectionName = h3.firstChild.pathname.replace(/\//,""); var sectionText = h3.textContent.replace(/\s*$/,""); if (sectionText == "\u25a0") { sectionText = sectionName; } this.text.innerHTML += '<h2>[http://anond.hatelabo.jp/'+sectionName+ ":title="+sectionText.replace(/^\u25a0/,"").replace(/]/g,"&#93;")+"] "+ '<a href="http://b.hatena.ne.jp/entry/http://anond.hatelabo.jp/'+sectionName+'">'+ '<img src="http://b.hatena.ne.jp/entry/image/http://anond.hatelabo.jp/'+sectionName+'">'+ "</a></h2>\n"; h3.firstChild.name = sectionName; var li = document.createElement("li"); li.innerHTML = '<a href="#'+sectionName+'">' + sectionText.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">") + "</a>"; var nextSibling = 0; for (var i in this.list) { if (nextSibling < i && i < sectionName) { nextSibling = i; } } if (nextSibling) { this.outline.insertBefore(li, this.list[nextSibling]); } else { this.outline.appendChild(li); } this.list[sectionName] = li; } var outline = new Outline(); function CC(day) { this.li = document.createElement("li"); this.li.innerHTML = '<a href="/'+day+'" target="_blank">' + day + "</a>"; this.day = day; this.n = new Array(); } CC.prototype.pp = function(id) { this.n.push(id); if (this.n.length > 10) { this.li.innerHTML = '<a href="/'+this.day+'" target="_blank">' + this.day + "</a> " + this.n.length; } else { this.li.innerHTML += ' <a href="/'+id+'" target="_blank">*</a>'; } } function Count() { this.count = document.createElement("ul"); this.list = new Array(); } Count.prototype.setup = function() { var parent = document.getElementById("body"); parent.insertBefore(this.count, parent.firstChild); } Count.prototype.append = function(day, id) { var nextSibling = 0; for (var i in this.list) { if (nextSibling < i && i <= day) { nextSibling = i; } } if (nextSibling == day) { this.list[nextSibling].pp(id); } else { var cc = new CC(day); if (nextSibling) { this.count.insertBefore(cc.li, this.list[nextSibling].li); } else { this.count.appendChild(cc.li); } this.list[day] = cc; cc.pp(id); } } Count.prototype.appendSection = function(section) { var id = section.getElementsByTagName("h3")[0].firstChild.pathname.replace(/\//,""); var today = id.match(/\d{8}/)[0]; var anchors = section.getElementsByTagName("a"); for (var i=0; i<anchors.length; i++) { if (anchors[i].href && anchors[i].host == "anond.hatelabo.jp" && anchors[i].pathname.match(/\/(\d{8})\d{6}/) && RegExp.$1 != today) { this.append(RegExp.$1, id); } } } var count = new Count(); function Hide(){} Hide.prototype.setup = function() { this.style = document.createElement("style"); this.style.id = "hide"; this.style.type = "text/css"; document.getElementsByTagName("head")[0].appendChild(this.style); var self = this; this.a = new Object(); this.a.visible = document.createElement("a"); this.a.visible.id = "visible"; this.a.visible.href = "#"; this.a.visible.innerHTML = "visible hide section"; // this.a.visible.setAttribute("onclick","document.getElementById('hide').innerHTML = 'div.hide {display: block}';document.getElementById('visible').style.display = 'none';document.getElementById('unvisible').style.display = 'inline';"); this.a.visible.addEventListener("click", function(){self.visible()}, false); firstPager_l.parentNode.insertBefore(this.a.visible, firstPager_l); this.a.unvisible = document.createElement("a"); this.a.unvisible.id = "unvisible"; this.a.unvisible.href = "#"; this.a.unvisible.innerHTML = "unvisible hide section"; // this.a.visible.setAttribute("onclick","document.getElementById('hide').innerHTML = 'div.hide {display: none}';document.getElementById('visible').style.display = 'inline';document.getElementById('unvisible').style.display = 'none';"); this.a.unvisible.addEventListener("click", function(){self.unvisible()}, false); firstPager_l.parentNode.insertBefore(this.a.unvisible, firstPager_l); this.unvisible(); } Hide.prototype.visible = function() { this.style.innerHTML = "div.hide {display: block}"; this.a.visible.style.display = "none"; this.a.unvisible.style.display = "inline"; } Hide.prototype.unvisible = function() { this.style.innerHTML = "div.hide {display: none}"; this.a.visible.style.display = "inline"; this.a.unvisible.style.display = "none"; } Hide.prototype.append = function(section) { if (section.className.match(/hide/)) { return; } section.className += " hide"; count.appendSection(section); } Hide.prototype.is = function(section) { return section.className.match(/hide/); } var hide = new Hide(); // main routine function grab(){ if (! document.body.innerHTML.match(/<div class="pager-r">(\d+)/)) { return; } var pages = RegExp.$1 -0; if (pages <= 0 || pages > 40) { // check error and limit 1000 entry return; } //pages = 2; firstPager_l.style.display = "none"; outline.setup(); hide.setup(); count.setup(); var mainbody = document.evaluate("//div[@class='body']", document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue; mainbody.innerHTML = "\n"; for (var i=1; i<=pages; i++) { cat(mainbody, i); } } // page load and concatenate function cat(container, page) { container.innerHTML += "<!-- page " + page + " -->\n"; GM_xmlhttpRequest({ method: "GET", url: "http://anond.hatelabo.jp" + location.pathname + "?page=" + page, onload: function(result) { result.responseText.match(/<div class="body">((.|\s)*?)\s*<\/div>\s*<\/div>\s*<div class="pager-l">/); container.innerHTML = container.innerHTML.replace("<!-- page " + page + " -->", RegExp.$1); if (! container.innerHTML.match(/<!-- page \d+ -->/)) { // document.documentElement.innerHTML = document.documentElement.innerHTML.replace(/(src|href)=\"\//mg, "$1=\"http://anond.hatelabo.jp/"); pickup(); } } }); } // pickup section at last cat() concatenate after function pickup() { var target = document.evaluate( "//div[@class='section' and child::*[not(@class='sectionfooter') and descendant::a[starts-with(@href,'http://anond.hatelabo.jp/2') or starts-with(@href,'/2') and not(child::span[@class='sanchor'])]]]", document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null); for (var i=0; i<target.snapshotLength; i++) { hide.append(target.snapshotItem(i)); } var tbs = document.evaluate( "//p[@class='sectionfooter']/a[2]", document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null); for (var i=0; i<tbs.snapshotLength; i++) { var tb = tbs.snapshotItem(i); if (tb.innerHTML == "\u30c8\u30e9\u30c3\u30af\u30d0\u30c3\u30af(0)") { hide.append(tb.parentNode.parentNode); } else if (! hide.is(tb.parentNode.parentNode)) { trackback(tb); } } } // count trackbacks function trackback(tb) { GM_xmlhttpRequest({ method: "GET", url: "http://anond.hatelabo.jp/" + tb.pathname.match(/\d{14}/), onload: function(result) { var link = result.responseText.match(/<a name="tb">(.|\s)*/)[0].match(/<li>\s*<a href="http:\/\/anond.hatelabo.jp\/\d{14}"/g); var n = link.length; for (var l in link) { var m = "/" + link[l].match(/\d{14}/); if (m in ignoreList) { n -= ignoreList[m]; } } if (n < trackbackThreshold) { hide.append(tb.parentNode.parentNode); } else { tb.innerHTML = tb.innerHTML.replace(/\)$/, "/"+n+")"); outline.append(tb.parentNode.parentNode); } } }); } })();