ときどきの雑記帖 RE* (新南口)
書を校するものは塵を掃うが如し
サイトの構成
大雑把に、今のサイトのディレクトリはこんな感じになっているのだけど
~kbk-- +-- index.html
|
+-- 雑記帖
|
+-- 正規表現メモ
|
+-- gawk
+-- sed
+-- grep
雑記帖そのものはさらにこういう構造になっている (多少の省略、変形あり)。
/------+-- index.html
+-- contact.html
|
+-- about
|
+-- ruins
|
+-- post (雑記帖本体) +-- index.html
| |
| +-- 記事本体のディレクトリ
| +-- 記事インデックスのディレクトリ
|
+--
post/index.html と index.html が同じような内容になってしまっているのがなんとも。 サイトの config ファイルで post というディレクトリを使わないように すればよかったのだけど、気がつくのが遅かった。
Coders
最初の方で
だから、自身もコーダーでテック文化の批評も行っているマーチュイ・スグロウスキーのように、 プログラミングに秀でている人々は、「解析能力に優れた自分なら、どのようなシステムも、 専門的な訓練など受けずに理解できる、その第一原理からすべてが理解できると考えがちだ。 人工的に作られたソフトウェアの世界で成功すると、あやうい自信を身につけかねない」と 批判する人もいる。
という文があって、どんな人なのだろうとググってみたがまるでそれらしい人が引っかからん>マーチュイ・スグロウスキー
英語表記で検索すればあるいは。とも思うけど、どんなスペルなんだこれ。
Ruby のソースコード
とあるblogでこんな一文を見かけた。
Ruby の Hash 実装 - blog.8-p.info
昔に趣味で Ruby, 仕事で Perl を書いていたころは「CRuby のソースコードはまあ読めるよねえ。でも Perl は謎のマクロが多くてまじできつい。」 と思っていたんだけど、2020年に CRuby のソースコードを読むと、全体的にコメントが少ないのと、とりわけ昔のコミットのコミットメッセージが 短いので、結構きつかった。
ふと、今のRubyのソースコードに対するRHGを書いたとしたら どんな感じでどのくらいのボリュームになるんだろうかと思った。
ソースコードそのものの規模の変化(増大)もあるんだろうけどデータ構造が結構変わってる(複雑になっている)よなあ。と。 ガーベジコレクションも色々手が入っているか。
データ構造についてはこんな記事 The Evolution of Ruby Strings from 1.8 to 2.7 | by Mehdi Farsi | RubyCademy | Medium もあるし、WEB+DB PRESS Vol.110|技術評論社 から連載でささださんが色々書いている。
- Rubyソースコード完全解説 Ruby hacking guideの通販/青木 峰郎/まつもと ゆきひろ - 紙の本:honto本の通販ストア
- Rubyのしくみ -Ruby Under a Microscope- | Pat Shaughnessy, 島田 浩二, 角谷 信太郎 |本 | 通販 | Amazon
- WEB+DB PRESS バックナンバー|gihyo.jp … 技術評論社
RHG はもう20年近く前の本になるのか…(遠い目)
Ruby のエラーメッセージ
Rubyの8進数と2進数の構文エラー文の違い - Qiita という記事で
なぜ8進数のエラーは親切なのか
Ruby1.8を実行すると090で既に「Illegal octal digit」というエラー文がでる。 そして、1.9になると「Invalid octal digit」と今の言葉に変化した。 このあたりは昔から親切なエラー文だったようだ。
8進数と他の数値リテラルのエラー文の違いは何なのか。 自分なりに好意的に解釈して推測すると、以下の通りである。 8進数だけ英字なしの0始まりで数値を組める。 そして、電話番号や時刻に対して数値を使い10進数のつもりで0始まりの8進数リテラルで書いてしまうケースがあり、 意図せずに8進数として使われたケースで誤りに気がつきやすいように8進数だけ親切にエラーを教えるようにしたのではないか。
しかし、2進数などのエラーはレアケースかもしれないが、それでもエラー文の内容はわかりにくいし頑張って紐解かないと分からないレベル。 自分に直接的な害はないけど、気になってしまう。
とあったのでちょっと確かめてみた。
>perl -e "$foo=08"
Illegal octal digit '8' at -e line 1, at end of line
Execution of -e aborted due to compilation errors.
>perl -e "$foo=0b2"
Illegal binary digit '2' at -e line 1, at end of line
Execution of -e aborted due to compilation errors.
>perl -e "$foo=0a"
Bareword found where operator expected at -e line 1, near "0a"
(Missing operator before a?)
syntax error at -e line 1, near "0a
"
Execution of -e aborted due to compilation errors.
>perl -e "$foo=0ba"
Bareword found where operator expected at -e line 1, near "0ba"
(Missing operator before a?)
syntax error at -e line 1, near "0ba
"
Execution of -e aborted due to compilation errors.
>python -c "foo=0o8"
File "<string>", line 1
SyntaxError: invalid digit '8' in octal literal
>python -c "foo=0b2"
File "<string>", line 1
SyntaxError: invalid digit '2' in binary literal
>python -c "foo=0oa"
File "<string>", line 1
SyntaxError: invalid octal literal
>python -c "foo=0ba"
File "<string>", line 1
SyntaxError: invalid binary literal
>ruby -e "foo=08"
-e:1: Invalid octal digit
foo=08
>ruby -e "foo=0b2"
-e:1: numeric literal without digits
foo=0b2
-e:1: syntax error, unexpected integer literal, expecting end-of-input
foo=0b2
>ruby -e "foo=0ba"
-e:1: numeric literal without digits
foo=0ba
-e:1: syntax error, unexpected local variable or method, expecting end-of-input
foo=0ba
なるほどこれはちょっとわかりづらいかも。
ソースコードだとこの辺か。
parse.y
static enum yytokentype
no_digits(struct parser_params *p)
{
yyerror0("numeric literal without digits");
if (peek(p, '_')) nextc(p);
/* dummy 0, for tUMINUS_NUM at numeric */
return set_integer_literal(p, INT2FIX(0), 0);
}
static enum yytokentype
parse_numeric(struct parser_params *p, int c)
{
int is_float, seen_point, seen_e, nondigit;
int suffix;
is_float = seen_point = seen_e = nondigit = 0;
SET_LEX_STATE(EXPR_END);
newtok(p);
if (c == '-' || c == '+') {
tokadd(p, c);
c = nextc(p);
}
if (c == '0') {
int start = toklen(p);
c = nextc(p);
8進数を扱っているのがこうで
if (c == 'o' || c == 'O') {
/* prefixed octal */
c = nextc(p);
if (c == -1 || c == '_' || !ISDIGIT(c)) {
return no_digits(p);
}
}
if (c >= '0' && c <= '7') {
/* octal */
octal_number:
do {
if (c == '_') {
if (nondigit) break;
nondigit = c;
continue;
}
if (c < '0' || c > '9') break;
if (c > '7') goto invalid_octal;
nondigit = 0;
tokadd(p, c);
} while ((c = nextc(p)) != -1);
if (toklen(p) > start) {
pushback(p, c);
tokfix(p);
if (nondigit) goto trailing_uc;
suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
return set_integer_literal(p, rb_cstr_to_inum(tok(p), 8, FALSE), suffix);
}
if (nondigit) {
pushback(p, c);
goto trailing_uc;
}
}
if (c > '7' && c <= '9') {
invalid_octal:
yyerror0("Invalid octal digit");
}
2進数がこう。
if (c == 'b' || c == 'B') {
/* binary */
c = nextc(p);
if (c == '0' || c == '1') {
do {
if (c == '_') {
if (nondigit) break;
nondigit = c;
continue;
}
if (c != '0' && c != '1') break;
nondigit = 0;
tokadd(p, c);
} while ((c = nextc(p)) != -1);
}
pushback(p, c);
tokfix(p);
if (toklen(p) == start) {
return no_digits(p);
}
else if (nondigit) goto trailing_uc;
suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
return set_integer_literal(p, rb_cstr_to_inum(tok(p), 2, FALSE), suffix);
}