門田匡陽
なんかこう、ずっとひっかかってたけど、門田氏とRitaさんが微妙に唄いかたが似てることに気付いた。黄金の鐘聴いてて思った。
なんかこう、ずっとひっかかってたけど、門田氏とRitaさんが微妙に唄いかたが似てることに気付いた。黄金の鐘聴いてて思った。
function Process () {
this.init.apply(this);
}
Process.prototype = {
init: function () {
var self = this;
this.stack = [];
this.rvalue = undefined;
setTimeout(function () { self.call() }, 0);
},
p: function (f) {
this.stack.unshift(f);
return this;
},
call: function () {
var self = this;
var f = this.stack.pop();
var thisObj = {};
thisObj.call = function (f, args) {
args = Array.prototype.slice.call(arguments);
f = args.shift();
self.stack.push(function () {
return f.apply(thisObj, args);
});
return "this";
};
this._rvalue = f.call(thisObj, this._rvalue);
if (this.stack.length) {
setTimeout(function () { self.call() }, 0);
}
}
};
window.onload = function () {
var ps = new Process();
ps.p(function () {
$("#content").append("<div>start!</div>");
}).p(function () {
function pow (x, n) {
function _pow (n, r) {
$("#content").append("<div>"+[n, r]+"</div>");
if (n == 0) return r;
return this.call(_pow, n - 1, x * r);
};
return this.call(_pow, n, 1);
}
return this.call(pow, 2, 1000);
}).p(function (r) {
$("#content").append("<div>end!"+r+"</div>");
});
};nemui
なんかくせになってきた。これすごい好きだ。「捨てたものを~」のところが鳥肌たつぐらい好きだ。
CD はずすと曲目と一緒に年号(のような4桁の数字)が書いてあるけど、これなんだろう。
きのうもだったけど……
やばいやばい。知らなかった。手元で既に使えるシンタックスっていう! (でも将来使えるかわからない予感) id:secondlife さんに教えてもらった。id:secondlife++ あと parse.y をながめてやりかたを覚えたw
この前の true/false のラムダを書いてみる。
# curry は http://subtech.g.hatena.ne.jp/cho45/20071119/1195420784
# 1.8
t = lambda {|x, y| x }.curry
f = lambda {|x, y| y }.curry
t[lambda {
puts "hoge"
}][lambda {
puts "fuga"
}][]
#1.9 head
t = -> (x, y) { x }.curry
f = -> (x, y) { y }.curry
t[-> {
puts "hoge"
}
][-> {
puts "fuga"
}][]
# or
t.
(-> {
puts "hoge"
}).
(-> {
puts "fuga"
}).()やばすぎる萌えすぎる。
メモ
t = -> (x, y) { x }
t = -> x, y { x } # 括弧いらないらしい
(1..3).map {|x| x * x }
(1..3).map(&-> x { x * x }) # このつかいかたはあんましなそう?
(1..3).map &-> x { x * x } # おなじ
car = -> x,*xs { x }
cdr = -> x,*xs { xs }
p car[10, 20, 30] #=> 10
p cdr[10, 20, 30] #=> [20, 30]
car = -> ((x,*xs)) { x }
cdr = -> ((x,*xs)) { xs }
p car.([10, 20, 30]) #=> 10
p cdr.([10, 20, 30]) #=> [20, 30]どういうとき一番うれしいかなぁ。ラムダ計算のやつは普通書かないし
hoge = ->&b{ b.yield b }
hoge.() {|x|
p x.lambda? #=> false
}
hoge.(&->x{
p x.lambda? #=> true
})これ記法によって挙動が変えられるってことで夢ひろがりんぐだけど、実際変わるメソッドがあったりするとびびりそう。どういう意図で入ってるんだろう。
#!ruby1.9 -v
s = -> x {-> y {-> z { x.(z).(y.(z)) } } }
k = -> x {-> y { x } }
i = -> x { x }
t = k
f = s.(k)
car = -> list { list.(t) }
cdr = -> list { list.(f) }
car = s.(i).(k.(t))
cdr = s.(i).(k.(f))
# ((lambda (n) (n n)) ((lambda (n) (n n)) (lambda (f x) (f (f x)))))
cn256 = -> n { n.(n) }.(-> n { n.(n) }.(-> f {-> x { f.(f.(x))}}))
# SII(SII(S(S(KS)K)I))
cn256 = s.(i).(i).(s.(i).(i).(s.(s.(k.(s)).(k)).(i)))
inputlist = -> list {
-> f { f.(list.first || cn256).(inputlist.(list.drop(1))) }
}
cn2num = -> cn { cn.(-> x { x + 1 }).(0) }
num2cn = -> n { -> f {-> x { (1..n).reduce(x) {|r,_| f.(r) } } } }
il = inputlist.([72, 101, 108, 108, 111].map(&num2cn))
p cn2num.(cn256)
p cn2num.(car.(il))
p cn2num.(car.(cdr.(il)))Ruby のコードに見えないすぎるw
黄金の鐘の歌詞があとかたもない。ハレルヤのところより看守は奴隷にパンを売りつけのところがなくなったのがすげー残念だなぁ。
class Hash
def put(key, value)
self[key] = value
self
end
end
a = { 1 => "foo", 2 => nil }
b = { 2 => "bar", 3 => "baz" }
p a.inject({}) {|r,(k,v)| r.put(k, b[k] || v) }
a.inject({}) {|r,(k,v)| r[k] = b[k] || v; r } # ← これがダサいML に投げるべきなんだろうなぁ……メールこわい……
というか []= が value を返すのはわかるけど、store (さっきしった) まで value かえさなくてもいいのに (Array#{push,unshift} は self をかえす)
どういう風に入れようか悩んでて (autopagerize_insert_before は microformats っていうのかなぁ……じゃあ名前なにがいいんかなぁとかいろいろ) いれてなかったけど、コミットされてたのでまいっかー的に……(他人まかせ)
それとは別に hAtom と rel="next" による microformats のルールを入れた。link rel="next" もマッチすべきかも
, { url : '^https?://.*'
, nextLink : '//a[@rel="next"]'
, insertBefore : '//*[contains(concat(" ",@class," "), " hfeed ")]/following-sibling::node()'
, pageElement : '//*[contains(concat(" ",@class," "), " hfeed ")]'
}clear cache のメニュー追加をかかないとなぁとおもってたらコミットされてたww CodeRepos++
どうも wiki clone がつくれない。なんか考えることが多くて、しかもちらばってて、まとまらない。だめすぎる……
でつくってみればいいんだろうけど、いまいちやる気がわかない。こんなのつくっても、って感じ…… Ruby で blosxom クローンつくらなかったのもこういう理由なんだよなぁ……blosxom クローンを Ruby で書いても Ruby がある程度わかってるならあれじゃ学習にならないし、書くならまともなのが書きたかったから、プラグインシステムをどうするかでずっと悩んでた。
しかし wiki clone だとユーザの書きこみがあったりするから、他の言語で勉強しながらつくるっていうのは結構荷が重い……
twitter とか、prototype.js をつかっているサイトだと Array#reduce がうわがきされるうえに挙動がちがっててうごかない。
こっちの prototype 拡張をやめる (関数よびだしにする) っていうの以外で解決できるならするけど、できないならやらない。
http://coderepos.org/share/changeset/2041
ごくごく簡単な XPath ジェネレータ/チェッカをくみこんでみました (Safari でのデバッグ用途が主目的)。siteinfo つくるなら基本的に http://labs.gmo.jp/blog/ku/2007/07/autopagerizexpath_autopagerize_ide.html をつかえばいいとおもうのでいらないと思います (さっきまで AutoPagerize IDE つかったことなかったw こりゃ便利ですね><)。
jAutoPagerize のアイコンをクリックするとテキストエリアがでます。Inspect ボタンをおすと要素選択して XPath を生成します。テキストエリア編集すると選択ノードにアウトラインがつきます。Safari でも動きます。jAutoPagerize のアイコンが表示されてないところでは javascript:XPathGenerator.open(); するとでてきます。
ノードから XPath つくるやつはちょー簡単に生成するのを前書いていたらしくて (test.user.js で getXPath... までうちこんだら autocompletepop された……) それをちょい改善してつかいました (ほとんどテストしてないからバグってるかも)。
getXPathByElement : function (target) {
var pathElement = "";
var node = target;
if (node.nodeType == 9 /*DOCUMENT_NODE=9*/) {
return ""
} else {
var tagName = node.tagName.toLowerCase();
if (node.hasAttribute("id")) {
// pathElement = tagName + '[@id="'+node.getAttribute("id")+'"]';
pathElement = 'id("'+node.getAttribute("id")+'")';
} else {
pathElement = arguments.callee(node.parentNode) + '/' + tagName;
if (node.hasAttribute("class")){
pathElement += '[@class="'+node.getAttribute("class")+'"]';
} else {
pathElement += '['+indexOf(node)+']';
}
}
}
return pathElement;
function indexOf (node) {
for (var i = 0, r = 1, c = node.parentNode.childNodes, len = c.length; i < len; i++) {
if (c[i].nodeName == node.nodeName &&
c[i].nodeType == node.nodeType) {
if (c[i] == node) return r;
r++;
}
}
return -1;
}
}
Ruby にしても JS にしても $1 $2 は、それらがどっから沸いてきたのかソースコードをうえからよんでいったときにわかりにくいので、できるだけ使たくない。暗黙的に代入されているし、$1 $2 っていう名前には全くマッチを連想させない (慣れればわかるけど……あと JS の場合は RegExp.$1 とかになるのでいくぶんマシ)。しかも $0 は実行中のプロセス名だから $0 と $1 の間に同じ $n なのに全く関連がない。
よっぽどめんどくさくない限りは Regexp.last_match したり m = str.match(r); する。(Perl のときは気にしない)
GreaseKit だと同じウィンドウで userjs が実行されるので、常に prototype 上書きされる危険性があって、これはどうしよもない。普通は標準の関数をわざわざうわがきしたりしないから問題ないけど、前述の Array#reduce みたいに、微妙な立場の関数でしかも名前がよくつかわれるやつは上書きされやすい。(というか実際には Array#map も上書きされているけど、こっちは挙動が同じなので問題になってないだけ)
Opera もたぶん同じウィンドウで実行されるから同じ問題をもっていると思うけど、あんまり調べてない。
解決法:
あとたぶんこういう関係 (unsafeWindow的な意味で) jAutoPagerize + Safari + GreaseKit だと XSS ふんでそうな感じがするのでチェック必要だと思う。(ちょっと考えたけどとれちゃうな…… http://coderepos.org/share/changeset/2050 修正した。ほかにもある予感……)
(Greasemonkey だとウィンドウが別れているのでだいだい問題おきない。なぜ unsafeWindow が GM にはあって、他のにはないのかをよく考えて使わないとだめですね><)
あれ r2050 じゃ解決になってないよね…… siteinfo を外からアクセスできるようにしたらだめだな。
r2051 でたぶん解決。Safari でつかうのは危険なかおりがプンプンする。
nanto_vi さんのコメントで原因が判明したので試行錯誤してコミットした。
http://coderepos.org/share/changeset/2053
var x = new XSLTProcessor();
var t = [
"<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>",
"<xsl:output method='html'/>",
"<xsl:template match='/'>",
"<html><head><title>", title, "</title></head><body/></html>",
"</xsl:template>",
"</xsl:stylesheet>",
].join("");
var d = document.implementation.createDocument("", "nice-boat", null);
var r = d.createRange();
r.selectNodeContents(d.documentElement);
d.documentElement.appendChild(r.createContextualFragment(t));
x.importStylesheet(d.documentElement.firstChild);
var ret = x.transformToDocument(d);
なんかしばらく新しく siteinfo をとりにいってキャッシュするところがうごいてなかったっぽい。なおした。
でも Safari だといまいち挙動不審で、たまにsiteinfo 全部 ({}) になってしまうことがある。textarea.replace(//, function () {}) がへんなのかも……めんどい
uneval を適当に実装してテストしてたらきづいた。