はてなキーワード: ADDとは
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
配列に格納したものと一致しないものだけをピックアップしたかったのだが、
配列の中にその値があるかどうかの比較のしかたがわからずfor文でまわしました。
なんとなく感覚でequals()と==をつかいわけているが、もしかしたら違うかもしれない。
classのインスタンスというかイニシャライズに相当する書き方がわからず、
初期化が必要なクラスをつくることができず、ひとつのクラス内でダバダバ関数を書いている。
} catch(ArithmeticException e) {
System.err.println("エラー" + e.getMessage());
関数ごとにこんな風にいちいち書いてみたが、もっといいやり方があるきがする。
// デバック用出力関数
private void fDebug(String msg) {
if (!DEBUG_FLG){ return;}
System.out.println(msg);
}
挙句、こんな関数を作った。俺はバカかとおもった。
ログ出力用のヤツまでつくってしまった。いったいこれはどういうことだろう。
昔し、配列のsortを教えてもらった記憶があるのだが実はいまだにできない。
しかたが無いのでaddで任意の位置に足しているが、それをやるにもループ、配列.size()で分岐しながらなのでカッコワルイ。
勢いでつくった関数にオプショナルで引数を追加したくなったのだが、やりかたがわからなかったので諦めた。
Eclipseで一気に複数行をコメントアウトするような方法がわからない。
→わかった! ctrl+/だ! おー、便利。
気持ち悪いループとbreak文だらけになってしまいわかり難いのでラベルをつけた。
「label:」みたいにすればいいらしい。だが根本的に間違っている気がする。
Integerとintみたいなものを区別せずに使っている。実際何が違うのかわからないけど動くからいいやとかおもってしまっている。
@Overrideってなんだろう。
参照が深くなりすぎてしまって、ループの中でわざわざ変数を宣言しなおしている。
DDDDD masuda = AAAA.BBBB().CCCC(ohdeyansu);
ookamiotokoto = masuda.funga() + masuda.hajimeruzamasu();
どうなんだろうか。
何か計算結果がおかしいなとおもったら int * (int/int) で、分母が計算途中で丸められてた。
int * (float)(int/int) こんな回避の仕方をしてしまったのだがいいのだろうか。
たいしたことをしていないのだがやたらとコードが長くなる。
どうにかならんものか・・・。
l:http://ustream.tv/channel/knnkandas-show
2007/08/03
[03:36] <ustreamer|5968> : wwww
[03:36] <otsune> : 今朝映ってるのを見ました
[03:37] <eimei> : あーあ
[03:37] <obacan2> : otsuneしミーハー扱いw
[03:37] <yuiseki> : ちわちわ!
[03:38] <ustreamer|5968> : 神田さん、そこで何かしましょうよ。 ○○生活とか。
[03:38] <VoQn> : 全然原稿書く気ないwwwwwwwww
[03:38] <ustreamer|6308> : 動画とまた
[03:38] <mindia245> : 動画とまた
[03:38] <ustreamer|9426> : いつもながら頑張りますね
[03:38] <ustreamer|5968> : とまた・・・・
[03:40] <yuiseki> : ついった効果かな?
[03:40] <ustreamer|9426> : mixiのせいじゃない?
[03:40] <suVene> : I'm Freanch
[03:40] <ustreamer|9426> : そんなことしていて原稿大丈夫?
[03:40] <mindia245> : www
[03:40] <otsune> : suVene: おいおい嘘付け!!!
[03:40] <ustreamer|6764> : なんの原稿かくんすか?
[03:41] <ustreamer|6764> : あぁーいまの状態ですね。。。
[03:41] <yuiseki> : みんなでライフハック考えるの?
[03:41] <ustreamer|6764> : 今日のグーグルの書きましょうよ
[03:41] <otsune> : Ustreamでブレインストーミング
[03:41] <suVene> : アイデアは帽子の中に入ってる。
[03:41] <ustreamer|7738> : 選挙おつかれさまー
[03:42] <ustreamer|6764> : ・・・・・・・・
[03:42] <obacan2> : 大学を運営する際にはセカンドライフで講義をするとブランディングに有効というlifehacksはどうか
[03:42] <otsune> : それどっかで聴いたぞ
[03:42] <obacan2> : 慶應でっす
[03:42] <ustreamer|6764> : くtしゃみw
[03:43] <ustreamer|6764> : 寝てください、○○りちゃん
[03:43] <ustreamer|6764> : まよですw
[03:43] <VoQn> : jamaicanを召喚できれば60Viewerは超える
[03:44] <obacan2> : www
[03:44] <suVene> : ジャマイカにいる。
[03:44] <ustreamer|6764> : そんなVIEW増やしてどないするんですか。。。
[03:44] <otsune> : 招集?
[03:44] <obacan2> : おもしろいのはどう考えてもカウボーイハットの人
[03:44] <ustreamer|6764> : どんだけぇー
[03:44] <ustreamer|7738> : また出るの!!?
[03:44] <otsune> : 3年後?
[03:44] <suVene> : 何から頭を守っているのか。
[03:44] <suVene> : カミカミw
[03:45] <yuiseki> : つぎは政見放送もカウボーイハットで!
[03:45] <ustreamer|6764> : 小島よしお
[03:45] <otsune> : ヒント:帽子が本体
[03:45] <ustreamer|6764> : 原稿やりましょうよ、、、
[03:46] <obacan2> : まず書き出しの40文字を
[03:46] <ustreamer|6764> : まっよでーすw
[03:46] <VoQn> : Who is megane?
[03:46] <yuiseki> : だれだれ
[03:46] <ustreamer|6764> : あぁー
[03:46] <otsune> : こんばんわ
[03:46] <obacan2> : ぬこだ
[03:46] <suVene> : こんばんは。
[03:46] <ustreamer|6764> : 年ばれるぞ、すっぴんw
[03:47] <otsune> : miyagawaさんに聴いたら「たぶん神田さんの彼女じゃない?」と言われたが、真相は
[03:47] <suVene> : 帽子の中の人。
[03:47] <ustreamer|6764> : たぶんてwwww
[03:48] <otsune> : 「やめてー」って
[03:48] <ustreamer|6764> : しかし、接続重たいですねぇー
[03:48] <suVene> : 音声だけ聞くと、危ないシーン
[03:48] <otsune> : 退場
[03:48] <ustreamer|6764> : P2Pでも、純粋なP2Pじゃないですよね?
[03:48] <ustreamer|6764> : 神田さんの声だけ
[03:48] <obacan2> : エコーかかってないですよ
[03:49] <eimei> : 回ってない
[03:49] <suVene> : 普通に聞こえます
[03:49] <otsune> : UstreamはFlash Media Serverでクライアントサーバー式だと思うから、P2Pじゃないはず
[03:49] <ustreamer|7738> : 第二の荒木飛呂彦めざして不老不死がんばって
[03:49] <ustreamer|6764> : はうってんじゃないですか
[03:49] <obacan2> : イヤホンするのがいいのかなとか
[03:49] <ustreamer|6764> : そりゃ、2重に聞こえますよ
[03:50] <ustreamer|6764> : そうですねw
[03:50] <obacan2> : え?なにこれ!!!すげー
[03:50] <obacan2> : うるさいです
[03:50] <ustreamer|6764> : 耳入れると、声でかすぎっす。。。
[03:50] <ustreamer|6764> : 耳入れないとだったw
[03:50] <obacan2> : 逆じゃね?
[03:50] <ustreamer|6764> : かんださん
[03:51] <ustreamer|6764> : タイゾーさんへの、質問ありますか?
[03:51] <suVene> : おもろいのは神田さん
[03:51] <obacan2> : すっかりアイドルだ!
[03:51] <ustreamer|6764> : 代議士
[03:51] <obacan2> : たしかにこれやっちゃうと公職選挙法にひっかかる
[03:51] <ustreamer|6764> : すぎむらw
[03:51] <ustreamer|6989> : こばわー、ご無沙汰です
[03:52] <wanderingdj> : ノシシ
[03:52] <otsune> : 「/nick hogefuga」で名前変更できる
[03:52] <ustreamer|6764> : 英語だし。。。
[03:52] <obacan2> : 「/nick hogehoge」で名前かえられる
[03:52] <wanderingdj> : 選挙どうやったん?
[03:52] <VoQn> : /nick jamoican
[03:53] <yuiseki> : knnkanda++
[03:53] <VoQn> : できないじゃん
[03:53] <suVene> : 小学生並みのギャグだ。
[03:53] <oquno> : knnkanda++
[03:53] <suVene> : or 八百屋さん
[03:53] <wanderingdj> : うそこけ、ウチの選挙区じゃないからチェックしーひんやったん
[03:53] <wanderingdj> : ノ
[03:53] <otsune> : ギャグが分かりやすいのが神田さんの芸風
[03:53] <obacan2> : つ比例区
[03:53] <wanderingdj> : ジャスラックがクルゾ
[03:54] <suVene> : なんか聞いたことある
[03:54] <VoQn> : めちゃテンション高いな
[03:54] <ustreamer|6764> : チャットしたら収拾つかなくなるし、現に原稿できてないじゃないですか。。。
[03:54] <obacan2> : JASRACのものですが
[03:54] <suVene> : そのうち、画面から見えなくなる。
[03:54] <wanderingdj> : 現実逃避手伝いage
[03:54] <ustreamer|6764> : あぁー。現実逃避だ。明日締め切り間に合わないんじゃないですか?
[03:54] <yuiseki> : ゾーンに入るまでが大変
[03:54] <obacan2> : 1200字に現実逃避てw
[03:55] <nishikokura> : nick/ パンデイロ
[03:55] <ustreamer|6764> : 1200wなら一時間で終わるのに。。。
[03:55] <knnkanda> : あらら
[03:55] <knnkanda> : おもくなってきた
[03:55] <knnkanda> : こっちで原稿うったほうがはやそうな気がしてきた
[03:55] <obacan2> : うごいてないなあ
[03:55] <otsune> : うごいた
[03:55] <nishikokura> : 音聞こえないす
[03:55] <ustreamer|6764> : P2Pで、この重さはしんどいなぁ、、、。音拾えてないし
[03:56] <yuiseki> : おとがない
[03:56] <wanderingdj> : KNN氏がお題を出してみんなで答える、と
[03:56] <wanderingdj> : 集合知だ!
[03:56] <obacan2> : knnkanda++ それ期待>ライブ原稿執筆
[03:56] <VoQn> : 夜があける前に原稿が間に合うのか
[03:56] <knnkanda> : 曼荼羅とは、タテ3つヨコ3つの9つのマスに
[03:56] <obacan2> : きこえた
[03:56] <ustreamer|6764> : ○×をいれ、三個並んだら勝ち
[03:56] <wanderingdj> : で、適当にコピペして唐沢メソッドで原稿完成
[03:57] <otsune> : ゲントウシャしかつかえねー
[03:57] <noraDJ> : 名前変更てし
[03:57] <knnkanda> : アイデアをだしていくアイデアですが、本のような長尺ものの原稿を書く場合の章建てに便利なのだ。
[03:58] <noraDJ> : で、何がテーマなん
[03:58] <eimei> : やっぱり、画は止まってても音が聞こえる方がストレスないね。
[03:58] <obacan2> : 録画録画
[03:58] <suVene> : アイデアがこぼれる
[03:58] <ustreamer|6764> : キャプられて、2chにあがりますよ、、、ww
[03:59] <noraDJ> : トランスフォーマは日本のトミーが輸出して逆輸入アニメがヒットした稀有な例
[03:59] <obacan2> : wwww
[03:59] <VoQn> : 録画してあとで文字起こしすれば原稿出来る
[03:59] <obacan2> : バカがやってくれる(可能性も)
[03:59] <otsune> : 原稿起こしをリンデンドルで支払う
[03:59] <ustreamer|6764> : 無駄に能力高い人が暇してますからね、日本。
[03:59] <noraDJ> : はてなポイントで支払いせい
[03:59] <obacan2> : ついったーじゃないすか
[04:00] <ustreamer|4251> : twitterからきました
[04:00] <suVene> : ここで脱ぐと50人。
[04:00] <ustreamer|9426> : mixiで知った
[04:00] <noraDJ> : ついったんからきますた
[04:00] <otsune> : twitterがなければUstreamは非常に使いにくいだけのサービス
[04:00] <obacan2> : > otsune それは気づかなかった
[04:01] <noraDJ> : 眠り実況はすでにねとらじでやってる
[04:01] <otsune> : 他人がtwitterのログを見ているのを見るのも面白いな
[04:01] <ustreamer|9426> : 明日が早いので、もう寝ます。頑張ってください!
[04:02] <noraDJ> : 乙>9426
[04:02] <obacan2> : プライバシーを削れば削るほど有利にはたらく時代は幸福なのかしらん
[04:02] <ustreamer|6764> : はい、原稿書くか、寝るかしましょう。
[04:03] <ustreamer|6764> : こわれてきた、、、
[04:03] <ustreamer|9987> : KANDA's high
[04:03] <ustreamer|6764> : おぉー選挙本。版元は?
[04:03] <noraDJ> : Usteramなんぞやってないで寝る。これぞlifehack
[04:03] <knnkanda> : 1.選挙にでるまで
[04:03] <knnkanda> : 2.選挙にでるいきさつ
[04:04] <knnkanda> : 3.選挙にでてみたら
[04:04] <otsune> : せっかく選挙に出たんだから、選挙体験記出してくれないと
[04:04] <knnkanda> : 4.選挙がおわって
[04:04] <suVene> : 新人がつくったプレゼンのようだ
[04:04] <otsune> : 選管に質問に行った時のPodCastはえらく面白かったな
[04:04] <VoQn> : 5.次の選挙に勝つには
[04:04] <noraDJ> : マジレスすっと1-4まで真面目に書くと、とんでもない量にならないか?
[04:05] <obacan2> : 誰か正規表現かいてあげたらどうですか!
[04:05] <ustreamer|6764> : 本の中で、アンケートやりましょう
[04:05] <yuiseki> : ついったーのFav機能みたいなのほしいよね
[04:05] <suVene> : IRC
[04:05] <obacan2> : いいかおww
[04:05] <yuiseki> : ☆
[04:05] <komaq> : あくびうつったwwww
[04:05] <suVene> : IRCに直接つなげば、ログとれるのでそれから。
[04:06] <noraDJ> : 興味があるのは、供託金の出所だよな
[04:06] <ustreamer|6764> : えぇ
[04:06] <otsune> : 話によるとアメリカ移住する資金だったのか
[04:06] <ustreamer|6764> : そりゃそうでしょ
[04:06] <otsune> : s/のか/とか/
[04:07] <ustreamer|6764> : ブログに書いたことがいえるのは、有名になった人だけですよ
[04:07] <ustreamer|6764> : 一般のライターは、言いたいことすらいえないのが現状ですってw
[04:07] <noraDJ> : しかしまぁなんだな、Mac雑誌の頃から進化してない神田氏に燃え
[04:07] <suVene> : ustream の IRC に直接発言できるAPI 公開されてればいいのに
[04:07] <ustreamer|6764> : 笑>noraDJ
[04:07] <otsune> : KNN神田さんの場合は、言いたい事が言えなくても無理矢理言ってしまう印象
[04:08] <knnkanda> : http://knnarchive.jugem.jp/
[04:08] <obacan2> : web2.0といえども、情報は結局、ブランドが無いと価値が認められないことが多い印象
[04:08] <ustreamer|6764> : ごもっとも>obacan2
[04:08] <otsune> : suVene: たぶんFlashのsocketでIRCプロトコルしゃべっているから、APIも糞も無くてIRC直で繋ぐしか無い
[04:09] <suVene> : JavaAppletだったころは、なんかプロトコルあったのかなと
[04:09] <ustreamer|6764> : しらんがなw
[04:09] <yuiseki> : ライターww
[04:09] <otsune> : むりむり
[04:09] <yuiseki> : みんなが教えてくれたら便利だなw
[04:09] <ustreamer|6764> : あつい!
[04:09] <obacan2> : こわい
[04:10] <obacan2> : いま気づいた、jugemとは微妙にセンスいいなあ
[04:10] <ustreamer|6764> : じゃ、神田さんのニコニコ動画にいたずら書きして寝ます
[04:10] <obacan2> : 検索したいならはてなダイアリーだとおもうけど。タギングがべんりだし
[04:11] <ustreamer|6764> : あげんのは、めんどいーw
[04:11] <obacan2> : せつめいしづらい部分ですね
[04:11] <otsune> : 1日単位で編集するが、見出しで擬似的に分割は出来る
[04:11] <suVene> : 見出しつけることによって、permalink つくのでは。
[04:11] <noraDJ> : 見出し記法で一日いくつでもエントリかけます
[04:12] <noraDJ> : きにしない
[04:12] <ustreamer|6764> : ま、はてなのことは、淳也さんにお願いして、改良してもらいましょう。
[04:12] <obacan2> : すごく個人的な使い方の紹介で恐縮なんですけども
[04:12] <yuiseki> : shi3zさんもぶーぶーいってた
[04:12] <suVene> : キーワード切れるのでは。
[04:12] <suVene> : 有料?
[04:12] <obacan2> : 有料です
[04:12] <obacan2> : 180円?
[04:12] <noraDJ> : いいじゃん無駄なりんく
[04:12] <otsune> : 「はてなキーワードリンクがウザい」ってのはやはり良く有る印象なんだ
[04:13] <obacan2> : 設定できます、手間だけど
[04:13] <nanashi20070803> : あるあるw 欲しいトコについてないのって
[04:13] <noraDJ> : いちいち気にするのが「いかにもわかってます」的でいやだね
[04:13] <ustreamer|6764> : チャットでマッシュアップ
[04:13] <noraDJ> : てきとーでいいじゃん
[04:13] <otsune> : 必殺「気にしない」でたー
[04:14] <ustreamer|5345> : hey wanker, put the cancer stick out!
[04:14] <obacan2> : knnkandaさんてセカンドライフは日本で流行すると踏んでるんでしたっけ
[04:14] <noraDJ> : 気にしないとすごいトコロと繋がりますよ
[04:14] <ustreamer|6764> : 電話で起こしますよw
[04:14] <obacan2> : www
[04:14] <yuiseki> : オンライン飲み会
[04:14] <ustreamer|5345> : that better be a malboro if you wanna be a real cowboy....
[04:15] <otsune> : cowboy!
[04:15] <noraDJ> : he is digital cowboy!
[04:15] <otsune> : LUCKY STRIKE!
[04:15] <noraDJ> : とかほざくてすt
[04:15] <ustreamer|5345> : LLLLLLLLLLLLL
[04:15] <obacan2> : アバターみたいなあんなキモい見た目のキャラがすきなのかな、日本人は
[04:15] <obacan2> : ポストセカンドライフのインターフェースはどうなるんだろ
[04:16] <nanashi20070803> : homeはどうなんだろ…。PS3持ってるから気になる。
[04:16] <otsune> : Second Lifeのアバター改善にビジネスチャンス
[04:16] <ustreamer|5345> : first time trying hash, huh cowboy?
[04:16] <noraDJ> : DQがセカンドライフになるんじゃないかと思う
[04:16] <obacan2> : アバター売ってるひと居ましたよね
[04:16] <suVene> : 韓国あたりから出て来そうな。
[04:16] <ustreamer|2478> : アレしてください
[04:17] <ustreamer|6764> : ってか、原稿・・・
[04:17] <ustreamer|6764> : おやすみなさぁーい
[04:17] <obacan2> : いよー
[04:17] <obacan2> : ぽん
[04:17] <nanashi20070803> : パン!
[04:17] <noraDJ> : はん
[04:17] <ustreamer|2478> : ぽん!
[04:17] <otsune> : フェイント
[04:17] <suVene> : ウケルw
[04:17] <ustreamer|6764> : どんだけぇーw
[04:17] <ustreamer|6764> : おやすみなさいまし。。。。
[04:18] <VoQn> : 結局書かないのかwwwww
[04:18] <otsune> : これ締め切りぶっちぎってる時は気まずいな
[04:18] <obacan2> : ライブ始める前にツイッターで告知が必須!!!
[04:18] <ustreamer|6764> : 寝るのに時計してるしw
[04:18] <suVene> : 始まってからでもOK。
[04:18] <otsune> : 始めたら告知でok
[04:19] <ustreamer|6764> : CMつけてうりましょw
[04:19] <ustreamer|6764> : 人集めますよw
[04:19] <otsune> : ロフトプラスワンで公開中継するか
[04:19] <obacan2> : 電通×セカンドライフ×knnkanda?
[04:19] <VoQn> : これをadd http://twitter.com/ustreamchecker
[04:19] <noraDJ> : おやすも
[04:19] <otsune> : おつかれさま
[04:20] <nanashi20070803> : おやすまなさい
[04:20] <suVene> : おつです
[04:20] <Lian> : お疲れさまー
[04:20] <VoQn> : おつかれさまでしたー
[04:20] <knnkanda> : good night every one!!!
[04:20] <yuiseki> : おつーー
[04:20] <knnkanda> : xxxxxxx
[04:20] <ustreamer|2478> : またきます
[23:48] <otsune> : YLL
[23:49] <otsune> : foobar.ynk
[23:49] <otsune> : good
[23:50] <otsune> : 麺麺
[23:50] <otsune> : 男男
[23:50] <otsune> : 燃燃
[23:50] <otsune> : 男萌
[23:52] <otsune> : ひさしぶり
[23:52] <otsune> : pinoko
[23:52] <otsune> : YNK! YNK!
[23:53] <otsune> : are you youpy?
[23:53] <otsune> : Chiba, Shiga, Saga
[23:53] <otsune> : もう遅い。ドアの外に居るよ
[23:54] <otsune> : 私はクレタ人です。嘘をつきません
[23:54] <otsune> : 後ろの壁のシミが顔に見える
[23:55] <otsune> : 一見優しい人が実は一番ヤバいひと
[23:56] <otsune> : もう一度英語でしゃべって
[23:57] <otsune> : ynkはジャマイカ人疑惑
[23:59] <otsune> : All your base are belong to us
[00:01] <otsune> : moeboe--
[00:02] <otsune> : http://ameblo.jp/moeboe/entry-10034286555.html ついったん描いた人か
[00:04] <otsune> : tumblrのurlどれ
[00:04] <otsune> : それAdd Friendしてるな
[00:05] <otsune> : kotorikoがいい具合になってきました
[00:05] <otsune> : 「はてなの人はよく分かんない/萌えぼえ」でtumblrしとく
[00:09] <otsune> : そろそろ早口言葉コーナーを再開
[00:10] <otsune> : このUstreamみてたら嫁さんがかえってきて気まずい
[00:12] <otsune> : playing piano
[00:12] <otsune> : play iTunes
[00:13] <otsune> : camera camera!
[00:13] <otsune> : 天然すぎる
[00:13] <otsune> : カメラのアングル変える発想は無いのか
[00:15] <otsune> : カメラをピアノに向けて
[00:16] <otsune> : 言えてない! > 新春シャンソンショー x3
[00:18] <otsune> : ぶらくら?
[00:19] <otsune> : たどたどしく
[00:19] <otsune> : 無理
[00:19] <otsune> : ニコニコ動画に登録するか
[00:20] <otsune> : 所帯持っていない人はナイトっぷりが激しい
[00:22] <otsune> : 実はkotorikoの戸籍を取ってる
[00:23] <otsune> : やばい。資産2兆超えバレる
[00:29] <otsune> : えなりかずきをイメージ
[00:30] <otsune> : かんでる
[00:30] <otsune> : 言えたか
[00:30] <otsune> : 嫁にウケてる
[00:30] <otsune> : 3回「らめぇ」
[00:31] <otsune> : report Abuse
[00:32] <otsune> : 安部譲二のモノマネで「アッチョンブリケ」
[00:33] <otsune> : ジャッキー・チェンのモノマネで「アッチョンブリケ」
[00:33] <otsune> : ジャマイカンに英語で「好きです」と
[00:34] <otsune> : 遠視用じゃないと無理か
[00:34] <otsune> : お色直しして
[00:36] <otsune> : このynkノリノリである
[00:36] <otsune> : speak english plz
[00:36] <otsune> : english! english!
[00:36] <otsune> : 子どもか > ハニートースト
[00:38] <otsune> : 「重量感溢れる/moeboe」
[00:39] <otsune> : 「aohige絶対非モテ/嫁」
[00:39] <otsune> : はっへれべれ
[00:39] <otsune> : camera
[00:40] <otsune> : camera!
[00:40] <otsune> : またか
[00:40] <otsune> : 天然すぎる
[00:40] <otsune> : ちょっとバイクでいってくる
[00:41] <otsune> : ピアノをカメラ前まで持ってきて
[00:41] <otsune> : 実は監督とメイクさんがカメラの外に控えている
[00:42] <otsune> : 生命線がやばい
[00:42] <otsune> : あんた地獄に落ちるよ/数子
[00:42] <otsune> : 嫁がynkに感情移入してる
[00:43] <otsune> : 見えないのに挨拶する嫁が天然過ぎる
[00:43] <otsune> : jamaicanが理解してる
[00:43] <otsune> : 一枚脱ぎました
[00:43] <otsune> : 次は下着?
[00:44] <otsune> : 語尾に「らめぇ」
[00:44] <otsune> : ynk++
[00:44] <otsune> : ynk++
[00:45] <otsune> : 変態だなんて褒められると照れるなぁ
[00:45] <otsune> : 57m
[00:46] <otsune> : ワゴン車に積み込みやすいな
[00:46] <otsune> : 156
[00:46] <otsune> : 156
[00:47] <otsune> : jkondoはUstream登録してない
[00:47] <otsune> : dankogaiは有った
[00:49] <otsune> : いま到着した
[00:56] <otsune> : 「あうあう」
[00:56] <otsune> : じゃじぇのば
[00:57] <otsune> : ヒント:みんなニートだから職業きいちゃダメ
[00:57] <otsune> : youpyはチームotsuneの仕事サボり
[00:57] <otsune> : 腹筋出来なくてもオーボエふけるの?
[00:58] <otsune> : オーボエインナーマッスル
[00:58] <otsune> : 「ぼきゅん」
[00:59] <otsune> : ぼきゅん++
[00:59] <otsune> : ぼっきゅんきゅん
[00:59] <otsune> : 覚えた
[00:59] <otsune> : いまから黒竜江省からイタ電するわ
[01:00] <otsune> : 行動でおわびしろ
[01:00] <otsune> : 水200ml一気飲み
[01:01] <otsune> : VoQn
[01:02] <otsune> : ReBlog
[01:03] <otsune> : 辛いものとは具体的に
[01:04] <otsune> : kotorikoは俺が好き過ぎる
[01:04] <otsune> : 「ynkは中本が好き/萌えぼえ」でtumblrしとくわ
[01:05] <otsune> : YNK! YNK!
[01:05] <otsune> : 「うんこはだめです/萌えぼえ」
[01:06] <otsune> : tumblr踏み逃げ禁止
[01:07] <otsune> : 0時過ぎに水をかけると増殖する
[01:07] <otsune> : 「ちんにゅる」
[01:09] <otsune> : 辛い物以外に好きな食べ物の話題
[01:09] <otsune> : うちの田舎では恐竜を良く食べるよ
[01:10] <otsune> : ありあ
[01:10] <otsune> : AERO
[01:10] <otsune> : VIPにスレ立ててくるわ
[01:11] <otsune> : 1:30からテレビ埼玉みるからそこまでやって
[01:12] <otsune> : 「gkbr=ゴキブリ/ynk」でtumblrするわ
[01:13] <otsune> : gkbrでgkbr
[01:13] <otsune> : ふつうだ
[01:14] <otsune> : youpyは今オレの隣にいる
[01:14] <otsune> : ないこうちょうktkr
[01:15] <otsune> : 正解:うちさいわいちょう
[01:15] <otsune> : 8710
[01:15] <otsune> : 不入斗←これは?
[01:16] <otsune> : げぇー
[01:17] <otsune> : 生き血
[01:17] <otsune> : 「はげっ」に嫁が馬鹿受け
[01:18] <otsune> : 嫁のパーツを交換する?
[01:19] <otsune> : なやむ
[01:19] <otsune> : フォロー
[01:19] <otsune> : そこは時差何時間?
[01:20] <otsune> : 「オレの嫁にしたい」と嫁が言ってる
[01:20] <otsune> : 「おそれいります」
[01:20] <otsune> : ダンプ転がして砂利運ぶのでかえります
[01:21] <otsune> : 「aerithさんありがとう。お世辞でもうれしい」と嫁が言ってた
[01:21] <otsune> : オレも絵本読むな。女の写真がのってるやつ
[01:22] <otsune> : なんだその音大生みたいな生活は
[01:23] <otsune> : ynkがジャイアンリサイタルやって
[01:24] <otsune> : 32歳ぐらい
[01:24] <otsune> : マックスヘッドルームのスタッフが作ってる
[01:25] <otsune> : 家庭用ゲーム機は何持ってる
[01:27] <otsune> : ヒント: 1,3,5,7,11
[01:27] <otsune> : もしかして数学のテスト苦手?
[01:28] <otsune> : 終わりー
/* 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
ttp://www.lingr.com/room/gauche/archives/2007/07/17#msg-12170016
ritus
Hi, I work with Google and looking for Japanese individual interested in working with Google in Tokyo. I am looking for someone with consulting/marketing background and programming/scripting skills. The location of the Google office is in Tokyo's Shibuya business area. If you know of anyone please feel free to forward my contact information.
Ritu Singh
ritus@googe.com
sorry the email is ritus@google.com
shiro
DO NOT SPAM!
基本的に他人を褒めることしかできない「はてなスター」で他人に罵詈雑言を浴びせる方法です。
ttp://s.hatena.ne.jp/star.add.json?uri=http%3A%2F%2Fd.hatena.ne.jp%2F【憎いあん畜生のID】%2F0000&title=【届けたい罵詈雑言(UTF-8パーセントエンコード)】&callback=Ten.JSONP.callback
これで
ttp://s.hatena.ne.jp/【憎いあん畜生のID】/blogs
にメッセージが登録されるよ!
ttp://d.hatena.ne.jp/【憎いあん畜生のID】/0000
なんてページは作れないから、誰が★を送ってきたのかすらわからないよ!
仕様が変わったり、僕の勘違いだったら大変だから、ご利用は計画的に!
1URIにつき1つしか登録されないから、複数のメッセージを送りたい場合は「0000」の部分を1回1回適当に変えようね!
まー、問題は、自分の
ttp://s.hatena.ne.jp/【ID】/blogs
なんて、ほとんどの人が見ないだろうってことだな。
Add Star押してもIDの残らないアノニマスターをここいらで始めてはどうだ。っていうかここになんでスターねーんだよ。
あ、ダジャレ、ごめんなさい。
それよかそれってweb拍手だろとか言う人、web拍手って1URLに1つ紐付けできるけど、その分ID申請しないとだめなんだぜ。(自分の所にCGI設置する場合は別だが)めんどくさ!
日々ブログを読んでいて「これはひどい」と思っても、コメントを書いたりトラックバックを送るのは敷居が高く、気持ちが十分に書き手に伝わらずに終わってしまうことも多いでしょう。はてな「これはひどい」は既存のブログにワンクリックで「これはひどいマーク」がつけられます。あなたの「これはひどい」と思った気持ちを「これはひどいマーク」に変えて、世界のブログに「これはひどいマーク」をつけよう!
ブログに書かれた各エントリーに表示された「これはひどい」ボタンをクリックすることで、簡単に「これはひどいマーク」を付けることができます。一つのエントリーに対して何個も「これはひどいマーク」をつけることができます。あなたがブログを読んで感じた「これはひどい」を気軽に「これはひどいマーク」にしてください。
自分のブログに「これはひどいマーク」を付けてくれた人には恨み言が書ける
自分が「これはひどいマーク」をつけた相手が自分のブログに「これはひどいマーク」をつけてくれた場合、その相手は1ヶ月間「炎上中」になります。また最近1ヶ月以内に自分のブログに「これはひどいマーク」を付けてくれた相手のブログには、「Addボタン」のとなりに「炎上ボタン」が表示されて恨み言を残すこともできます。
はてな以外のブログサービスをご利用中の方でも自分のブログに「これはひどいマーク」を付けられます。以下のコードを自分のブログに貼り付けください
<script type="text/javascript" src="http://h.hatena.ne.jp/js/Korewahidoi.js"></script>
世界日報社
javascriptで存在するほとんどのオブジェクトの実体はハッシュだよ。
var arr = [0,1,2,3];
とかをみると配列(人によってはリスト)に見えると思う。でも実際は違うんだ。
これは
var has = {0:0,1:1,2:2,3:3};
と基本的には等価なんだ。ただちょっと束縛されているメソッド(インターフェイス)が違うだけ。
ためしに
arr[4] = 4; arr['x'] = 'string'; arr[-1] = -1;
としてみよう。
Firebugで確認してみると[0, 1, 2, undefined, 4]というような値がかえってくるよ。
でもarr[-1]やarr['x']の値は保存されてないのかな?そんなことはないちゃんとアクセスできるんだ。
それどころかarr.xで'string'がかえってくるんだ。
別の例を見てみよう。
var fx = function(){}; fx[0] = 'somestring';
こうするとfx[0]に'somestring'が束縛される。
つまりfunctionも一つのハッシュだったんだ。
これでほとんどのものがハッシュだということが解ってくれたかな?
ハッシュじゃないのは文字列とか数字とかそいういシンプルなものだけなんだ。
ハッシュへはhash[name]でアクセスすることが出来る。
それ以外にもnameが演算子や空白を含まなくて頭が数字でない場合はhash.nameでアクセスできるんだ。
これでhash[name]が関数だったらhash.name(args)とできるよ。まるでメソッドみたいだね。
関数には名前を付けなくても使用可能だよ。
function(x){return x+x}(2); -> 4
関数宣言の書き方って次見たいの覚えてる人が多いんじゃないかな?
function funcname(args){ do something};
でもこれはsystax sugerだってことを知ってほしい。
上でも使ってるんだけど。
var funcname = function(args){ do something};
と等価になる。もちろんどちらの書き方でもかまわないよ。
ただ、(無名)関数を宣言してそれをfuncnameに束縛しているっていうことを理解しておくと便利だよ。
javascriptはレキシカルスコープを採用してるんだ。
レキシカルスコープなんていうと難しく感じるかもしれないけど、結構単純なんだ。
var x = 'global'; var fx1 = function(){return x}; var fx2 = function(){var x = 'local';return x}
これの実行結果は以下になるよ。
fx1() -> 'global' fx2() -> 'local' fx1() -> 'global'
fx2の変数xはほかの場所に影響しないんだ。これは関数の中と外ではスコープが違うからなんだ。
でも以下のような場合に注意してほしいな。
var x = 'global'; var fx1 = function(){return x}; var fx2 = function(){x = 'local';return x}
fx1() -> 'global' fx2() -> 'local' fx1() -> 'local'
fx2は自分のスコープに変数xがないからその外側スコープに探しに出かけたんだ。
つまり宣言文varはそのスコープに新しい名前を登場させる機能なんだよ。
別の場合を見てみようね。
var x = 'global'; var fx1 = function(){ var x = 'local'; return function(){return x} }; var fx2 = fx1();
x -> 'global' fx2() -> 'local'
この例だとfx2()の値がlocalになってるね。
なぜなら外側スコープっていうのは関数を評価した場所じゃなくて、関数を定義した場所の外側なんだ。
一つ上の例では実際に関数を返り値にしているね。
var fx1 = function(){ var x = 0; return function(){ x = x+1; return x; } }; var fx2 = fx1(); var fx3 = fx1();
fx2() -> 1 fx2() -> 2 fx2() -> 3 fx3() -> 1 fx3() -> 2
fx2とfx3の値が違うのはそれぞれ別の関数が作られるからだよ。
こんな風に関数が状態を持つことも出来るんだ。クロージャーとよんだりするよ。
関数がハッシュを使って複数の関数を返すとこんなことも出来るよ。
var fx = function(){ var x = 0; return { 'up':function(){ x = x+1; return x; }, 'down':function(){ x = x-1; return x; } } }; var obj = fx();
obj.up(); -> 1 obj.up(); -> 2 obj.down(); -> 1 obj.down(); -> 0
thisという機能があるよう。ちょっとだけつかってみるね。
var x = 0; var add = function(n){this.x = this.x + n; return this.x}; var mul = function(n){this.x = this.x * n; return this.x}; var obj = {'x':0,'do':add};
add(1); -> 1 add(1); -> 2 mul(2); -> 4 obj.do(); -> 1 obj.do(); -> 2 obj.do = mul; obj.do(); -> 4
thisは評価された場所によって値がかわるよ。
objの中にいるときはobj.xを扱うし、グローバルにいるときはグローバルのxを扱うんだ。
http://anond.hatelabo.jp/20070620200618を改訂してみたよ。
このぶんしょうがjavascriptを覚える上の一助になるとうれしいんだ。
あとここでつかってるハッシュは伝統的な意味。連想配列のことね。
突っ込みも大歓迎だよ。
javascriptライブラリMochiKitというのをご存知だろうか?
私はこのライブラリを採用して非常に開発が楽になったことから諸君にもおすすめをしたいのでサワリだけ紹介したいと思う。
配列を受け取り、それぞれを1加算した配列を返す処理を見てみよう
var arr = [1,2,3,4,5]; var v = map( function(x){return x+1}, arr);
v -> [2,3,4,5,6]
となる。
複数回同じ処理を別の配列に適応する場合は
var arr1 = [1,2,3,4,5]; var arr2 = [2,4,6,8,10]; var fx = function(x){return x+1}; var v1 = map(fx,arr1); var v2 = map(fx,arr2);
v1 -> [2,3,4,5,6] v2 -> [3,5,7,9,11]
とできる。しかしこれを書くのが面倒な怠惰な人々のためにpartialが用意されている。
var arr = [1,2,3,4,5]; var fx = partial(map,function(x){return x+1}); var v1 = fx(arr1); var v2 = fx(arr2);
v1 -> [2,3,4,5,6] v2 -> [3,5,7,9,11]
とできる。partialは関数の第一引数から順に値を指定した関数を作る関数だ。
この場合はmap関数の一つ目の値をfunction(x){return x+1}に指定した関数がfxに束縛される。
もう少々一般化して配列を受け取り、それぞれをn加算した配列を返す処理を考えてみよう。
var arr = [1,2,3,4,5]; var n = 10; var add = function(n,x){return x+n}; var fx = partial(map,partial(add,n)); var v1 = fx(arr); n = 1; var v2 = fx(arr);
v1 -> [11,12,13,14,15] v2 -> [11,12,13,14,15]
ここでv1とv2の値が等しい理由はちょっと考えてもらえば解ると思う。
もちろんaddという名前を考えるのが面倒な人は
var n = 10; var fx = partial(map,partial(function(n,x){return x+n},n));
と書いても問題ない。
では、配列を受け取り、それぞれを値をn加算したあとm倍した配列を返す処理をみてみよう。
既にn加算する処理は一度出てきているからそれを利用する。
var arr = [1,2,3,4,5]; var n = 10; var m = 2; var add = function(n,x){return x+n}; var mul = function(n,x){return x*n}; var addMul = compose(partial(mul,m),partial(add,n)); var fx = partial(map,addMul); var v = fx(arr);
v -> [22, 24, 26, 28, 30]
compose(f1, f2, ..., fN)はf1(f2(arguments))という評価をする関数をかえす。
つまりaddMul(n)の場合はpartial(mul,m)(partial(add,n)(N))と等価なのだ。
もちろん
var arr = [1,2,3,4,5]; var n = 10; var m = 2; var fx = partial(map, compose(partial(function(n,x){return x*n},m), partial(function(n,x){return x+n},n))); var v = fx(arr);
とかいてもよい。ただし名前を考えることの労力と、可読性を天秤にかける必要があるかもしれない。
ちなみに私は addMulを別の場所で使わない限り後者で書くことが多い。
にいってみてはどうだろうか。
http://anond.hatelabo.jp/20070612185517
Addしなきゃいいじゃん。過去ログだって公開されているんだし。まぁleaveしても表示されるのはbugだろうから運営にメールで苦情言えば。本来の使い方をしている相手にケチ付けるなんてどういう頭の構(
http://anond.hatelabo.jp/20070612072957
↑はコメントアウトを外すだけで、いつ使えなくなるかちょっとアレ。
というわけでせっかくだから各記事のタイトルの横にリンクを追加するようにした。
下のidをmasudaから自分のものに変えて使う。
タイトルの横に ← が追加されるので、クリックして言及しまくればいいんじゃないでしょうか。
// ==UserScript== // @name add masuda reference button // @description add masuda reference button // @namespace http://anond.hatelabo.jp/ // @include http://anond.hatelabo.jp/* // @exclude http://anond.hatelabo.jp/*/edit* // ==/UserScript== (function(){ id = 'masuda'; titles = document.getElementsByTagName('h3'); for(i = 0; i < titles.length; ++i){ d = titles[i].innerHTML.match(/\d{14}/); titles[i].innerHTML += '<a href="http://anond.hatelabo.jp/' + id + '/edit?title=Re: [anond:' + d + ':title]" class="edit">\u2190</a>'; } })();