2006年 05月 11日

今日のぺるる - grep, リファレンス

grep とリファレンスがわからなかった。

ちなみに一通りドキュメントは読んでみて、概念っぽいのはわかっているんだけど、実際の挙動がわからない、という感じ。ようするにだめだめ。とぴあさんに助けてもらいつつちょっとわかってきた。

[{:foo=>:a, :bar=>:b}, {:foo=>:c, :bar=>:d}].find {|i| i[:foo] == :a}[:bar]

っていう Ruby のコードを Perl で書きたい場合。

# 答え
(grep { $_->{foo} eq "a"} [{foo=>"a", bar=>"b"}, {foo=>"c", bar=>"d"}])[0]->{bar};
#以下間違い
# クロージャのあとにカンマは要らない
grep { .. }, [..];
# -> 演算子によって左辺がスカラ文字列に変換されてしまうらしい
# この場合 grep でヒットした配列の数の文字列に対してハッシュ操作を
# 行おうとするので、エラー
(grep { .. } [])->{bar};

リファレンスを実データに戻す文法がわからなかった。

$a = [1, 2, 3]; #=> $a is reference of array
@{$a}; #=> で array に戻る
# @($a) と書いて構文エラー

それと Hash ref, Array ref から直接アロー演算子使って中身を取り出すときの構文

$a = ["a", "b", "c"];
$a->[1]; #=> "b"
$h = {0 => "a", 1 => "b", 2 => "c"};
$h->{1}; #=> "b"

一番なるほど!て思ったのは $_

grep { $_ eq "a" } ("a", "b", "c");
foreach (@{$a}) {
print $_;
}

$_ ってよく見るけどなんやねんって思ってた。

grep {|$_| ..}

っていう Ruby 風の説明をされてよくわかった。


疑問

foreach (@{$a}) {
foreach (@{$b}) {
$_;
}
$_; #=> スコープは?
}

あとで実行してみよう。

foreach $i (@{$a}) {
foreach $j (@{$b}) {
print "$i, $j";
}
}

みたいにかけるのかな。my をつけるべき? (つけられる?) っていうか for と foreach は同じなのね

コメントでの指摘で修正

今日のぺるる $_ の続き。

my @a = ("a", "b", "c");
for (@a) {
for (@a) {
print $_;
}
print "\n  $_\n";
}
__END__
abc
a
abc
b
abc
c

ちゃんとブロックローカル (?) だった。

2006年 03月 26日

色じゃなかったんだ。タブだったんだ。

emacs がなかなか使えなかった理由はタブインデントをデフォルトでちゃんとしてくれないからだった。今までは色の設定を変えるのが面倒臭いからだと思ってた。

class Foo
\tdef initialize(hoge, huga)
\t\tfoooooooooooooooooooo(aaaaaaaaaaaaaaa,
\t\t                      bbbbbbbbbbbbbbb)
\tend
end

本当は上記のようにインデント (環境が変わってタブ幅が変わっても問題が起きないタブインデント) をさせたいんだけど、さすがに無理っぽいので、タブの部分だけちゃんとできていればいいことにした。

人それぞれ読みやすいインデント幅は違うから、誰にでも読みやすいソースを書くならタブでインデントすべきだと思ってる。でも全部タブにすればいいってわけじゃなくて、文字幅が重要なところには、ちゃんとスペースを使いたい、みたいな。

そんなにこだわる必要はないんだけど、少なくともタブインデントじゃないとコードを書く気がしないことに気付いた。いやむしろ、タブインデントにすると書きたくなる (謎)

2006年 03月 18日

ソースの色づけを復活 2

GeSHi - Generic Syntax Highlighter を使うようにした。対応言語が多いことと、シンタックスファイルを増やし易いことがいい感じ。ただし時々 well-formed じゃないエラーがでることがあるっぽい。

2006年 03月 17日

ソースの色づけを復活

pre だけ色付けするようにした。

前に Pure JavaScript で色つけていたことがあったけど、あからさまにブラクラだった。で、なんとなく思いついたのでもっかい別の方法で実装してみた。

なんていうか非常にローテクといいますか他力本願な方法でして、PEAR::Text_Hightlighter に Ajax で丸投げというソリューションでございますです。

<?php
header("content-type: text/xml");
require_once 'Text/Highlighter.php';
require_once 'Text/Highlighter/Renderer/Html.php';
$options = array(
'numbers' => HL_NUMBERS_LI,
'tabsize' => 4,
);
$renderer =& new Text_Highlighter_Renderer_HTML($options);
$hl =& Text_Highlighter::factory($_GET["lang"]);
$hl->setRenderer($renderer);
$ret = $hl->highlight($_GET["source"]);
echo '<div xmlns="http://www.w3.org/1999/xhtml">';
echo $ret;
echo '</div>';
?>

こんなスクリプト書いたら、あとは JSpre 要素列挙して投げてあげる。レスポンスを importNode して、pre と置き換える。みたいな。

でもこんなクソ簡単なスクリプトなのに IE ではちゃんとうごかない。importNode がだめなのか、それとも responseXML から importNode ができないのか……謎。

あーHtml.php の &nbsp; は全部 &#160; に置き換えた。DTD がないからエラーになる。

2006年 03月 14日

Ruby で、Ruby に限らず

やっぱ最初のころは Ruby のブロック引数が全く理解できんかった。yield をよぶとどこに飛ぶか、とか結構悩むと思うんだ。

each の「使い方」を先に覚えて、実行してみてやっとブロック引数の概念が理解できた。んで、「じゃあ自分で書くときはどうするんだ」とかでリファレンスを読むと yield とか書いてあって、でもそれ以上はリファレンス読んでもよく分からなかったから、てきとーにサンプル作ってみてやっと理解した。

それまで書いていたのが PHP とかいう謎言語だったので、Ruby が余計に神がかってみえた。Perl は読めなかったし、Python は知らなかったし。今は Perl とか Python を勉強しようと思っても、必要性が見当たらなくて書けない。所詮「勉強」にすぎなくなるから、やる気があんまり起こらない。しかし Perl はホントに、本当に読めない。map { hoge } hage {} @foobar みたいなのをよく見るけど、どういう仕組みで評価されてるのかよくわからない。

まぁ、とりあえず、自分は実装を触りながらじゃないとぜんぜん理解できない。頭が悪い上に「自分の今考えてること」に対してかなり不安を覚えるので、すぐにコンピュータで実行させて、考えていることがあっているのか間違っているのかを確定させたい。

あんまり頭の中で構造を考えないで、とにかく動かしてみる。一行書いて、p 書いて、実行して、ってのを繰り返す。しかもこれ、未だにこういう感じなのだ。数行書くごとに実行する。とにかく p を書きまくる。んで、暇なときにリファレンスを眺めて、「こういうことができるのか」ってまた書いて実行してみたりする。

だから、何か作ろうとしていないと、そもそもプログラムを書かないからなかなか理解できるようにならない。Perl も書いてみたらわかるかもしれないけど、Perl を使って書きたいものがない。気がつくと面倒くさくて Ruby を使ってる。だめじゃん。

2006年 02月 24日

面白いとき

  1. 機能を考える (だるい)
  2. 「これはいいんじゃね!?」と思う (たのしい)
  3. インターフェイス考える (だるい)
  4. はやく動かしたいと思いながら実装する (たのしい)
  5. 追加機能を考える (わりとたのしい)
  6. 2 番目へ
2006年 01月 26日

Ruby, Object#p method

class Object
def p
Kernel.p self
self
end
end
"aaa".p.gsub(/^a/, "b").p

みたいなのをたまに使う。self を返すので .p だけを付けたり消したりすればいい。たまに便利。殆どの場合上のコードを書くのさえ面倒くさくて結局 p obj とか一行書いてしまう。だめじゃん。

base64 の方法をよく忘れる

  • ruby -e 'puts [ARGF.read].pack"m"' filename
  • uuencode -m filename foobar
2006年 01月 18日

Brainfuck, 値のコピー

単純にコピーしようとしても無理みたいだ。ループカウンタは常にデクリメントされまくるので、一つの値を別のところにコピーする場合、元の値は一度破壊 (0化) するしかない。その後元の場所に値を戻す。

=initialize
+++++
? Array: 05 00 00
=Copy
I wanna copy the value from 0 to 1.
[->+>+<<]
? Array: 00 05 05
>>[-<<+>>]
? Array: 05 05 00

インタプリタに

    when ??
p arr

とか付け加えてデバッグ。