ときどきの雑記帖 RE* (新南口)
続・東京ワッショイ
新名称
映画「メジャーリーグ」が封印されたりしない? とふと思った。
- 新チーム名は「ガーディアンズ」。100年以上にわたって親しまれていた「インディアンス」の名はなぜ変わるのか<SLUGGER> | THE DIGEST
- 【MLB】インディアンスが球団名を「ガーディアンズ」に変更 | スポーティングニュース・ジャパン
あのマスコットマーク(ワフー酋長)は2019年からすでに使われなくなっていたのか(知らなかった)。
そういえばアトランタ・ブレーブスのアレとかNFLのあのチームの名前とかは?
ふむ。
Perl
Perlはプログラミングの副業に向いているのか PythonやRubyとの違いは? | 財経新聞
プログラミング言語のPerlは、ラリー・ウォール氏によって1987年に開発され、4年後の1991年に発表された。
なんだろうこの「不思議な」記述は。 これだとまるで1991年まで世に出ていなかったみたいじゃないか。
で、
Perl - Wikipedia をみると、
バージョン | 公開日 | 内容 |
---|---|---|
1.0 | 1987年12月18日 | 6台の VAX 機と6台の Sun 機のためのコンフィギュレーション管理制御システムのレポート作成ツールとして誕生した。 |
2.0 | 1988年6月05日 | ヘンリー・スペンサー作の美しい正規表現ライブラリを Perl 風にアレンジし、導入した。 |
3.0 | 1989年10月18日 | バイナリデータを処理できるようになった。 |
4.0 | 1991年3月21日 | O’Reilly&Associates, Inc. より Programming perl が発売されたのに合わせて公開された。 |
みたいな書かれ方をされていた。ひょっとして4.0のところの記述を「誤解」したのか?
書籍Programming Perlにあわせて1991年に公開されたのは4.0の話であって、 それ以前のバージョンもnet newsに投稿されていたから 4.0で初めて公開されたというわけではない。
ところでこの「歴史」の部分、いかにも英語版から翻訳したものですという 空気が感じられたのだけど、実際英語版を見ると
Early versions
Larry Wall began work on Perl in 1987, while working as a programmer at Unisys,[14] and released version 1.0 to the comp.sources.misc newsgroup on December 18, 1987.[28] The language expanded rapidly over the next few years.
Perl 2, released in 1988, featured a better regular expression engine. Perl 3, released in 1989, added support for binary data streams.[citation needed]
Originally, the only documentation for Perl was a single lengthy man page. In 1991, Programming Perl, known to many Perl programmers as the “Camel Book” because of its cover, was published and became the de facto reference for the language. At the same time, the Perl version number was bumped to 4, not to mark a major change in the language but to identify the version that was well documented by the book.[citation needed]
だいぶ違いますな(編集履歴はみていない)。
GNU gettext
たとえば……
- Python のソースコードはGitHub上にあり、公式ドキュメントは公式サイトの下にあります。日本語版ドキュメントも現在は公式サイトの下にあります。
- Ruby on Rails のソースコードはGitHub上にあり、公式ドキュメントは公式サイトの下 (Guides) / (API) にあります。公式ドキュメントのうちGuidesはYassLab (株) により日本語訳が提供されています。
- GNU gettext のソースコードはGNU Savannah上 にあり、公式ドキュメントは公式サイトの下にあります。日本語は存在しないようです。
- 日本語版がないときは機械翻訳を使う手もあります。大抵の場合、読まないよりも10000倍有益です。
- FactoryBot には公式ドキュメントのための独立したページはありませんが、ソースコード内の README.md や GETTING_STARTED.md が公式ドキュメントの役割を果たしています。
この流れで GNU gettextが例に出てくるのがよくわからん(なぜ?)。 まあそれはさておき、「公式な」「最新の」ものではないにしろ、(gettextのドキュメントの)日本語訳はあるにはある。 GNU gettext utilities とか。
gettext - GNU Project - Free Software Foundation によると
The latest release is 0.21, which can be downloaded from https://ftp.gnu.org/pub/gnu/gettext/gettext-0.21.tar.gz. For other ways to obtain gettext, please read How to get GNU Software.
現時点(2021年7月)の最新が0.21で、それに対して日本語版ドキュメントは0.18ベースだけど、 役に立たなくなるような大きな変更はないんじゃないかなあ(未確認) Savannah Git Hosting - gettext.git/blob - ChangeLog.1
ところで GNU gettext utilities にわたしの名前が残っているのはありがたくもありむずがゆくもあり。
かなり前に途中まで訳して放り出したのをここに置いていたことがあるのだけど、 それが使われたのだろうと認識している(どの程度それが現在のものに残っているのかはわからないけど)。
glob zsh 8
関数ポインター funcにどんなものが代入されているのか grepで簡単に調べてみる。
$ grep -e 'func =' glob.c
func = (int (*) _((char *, Statptr, off_t, char *)))0;
func = qualislnk;
func = qualissock;
func = qualisfifo;
func = qualisdir;
func = qualisreg;
s++, func = qualisblk;
s++, func = qualischr;
func = qualisdev;
func = qualiscom;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualflags;
func = qualdev;
func = qualnlink;
func = qualuid;
func = qualgid;
func = qualuid;
func = qualgid;
func = qualmodeflags;
func = qualnonemptydir;
func = qualtime;
func = qualtime;
func = qualtime;
func = qualsize;
func = qualsheval;
qn->func = func;
いくつか同じもの(関数)を代入しているのが目につくけど、 その周辺もみるとこんな感じ。
case 'R':
/* Match world-readable files */
func = qualflags;
data = 0004;
break;
case 'W':
/* Match world-writeable files */
func = qualflags;
data = 0002;
break;
case 'X':
/* Match world-executable files */
func = qualflags;
data = 0001;
break;
case 'A':
func = qualflags;
data = 0040;
break;
case 'I':
func = qualflags;
data = 0020;
break;
case 'E':
func = qualflags;
data = 0010;
break;
case 'r':
/* Match files readable by current process */
func = qualflags;
data = 0400;
break;
case 'w':
/* Match files writeable by current process */
func = qualflags;
data = 0200;
break;
case 'x':
/* Match files executable by current process */
func = qualflags;
data = 0100;
break;
case 's':
/* Match setuid files */
func = qualflags;
data = 04000;
break;
case 'S':
/* Match setgid files */
func = qualflags;
data = 02000;
break;
case 't':
func = qualflags;
data = 01000;
break;
dataという変数が「怪しい」すな。 この、複数の代入があるqualflagsの実体はどんなものかというとこう。
/* given flag is set in mode */
/**/
static int
qualflags(UNUSED(char *name), struct stat *buf, off_t mod, UNUSED(char *dummy))
{
return mode_to_octal(buf->st_mode) & mod;
}
大文字のUNUSEDは名前からしてコンパイラーの警告を消すためのマクロだろうと 判断してスルーして、行っているのはファイルの属性のチェックですかね。
もうひとつのqualtimeの方はというと
case 'a':
/* Access time in given range */
g_amc = 0;
func = qualtime;
goto getrange;
case 'm':
/* Modification time in given range */
g_amc = 1;
func = qualtime;
goto getrange;
case 'c':
/* Inode creation time in given range */
g_amc = 2;
func = qualtime;
goto getrange;
いかにもUNIXのファイル(の時間)に関するモノっぽいですね。 それぞれのcase節で代入されている g_なんちゃらという変数は グローバル変数っぽい?
/* time in required range? */
/**/
static int
qualtime(UNUSED(char *name), struct stat *buf, off_t days, UNUSED(char *dummy))
{
time_t now, diff;
time(&now);
diff = now - (g_amc == 0 ? buf->st_atime : g_amc == 1 ? buf->st_mtime :
buf->st_ctime);
/* handle multipliers indicating units */
switch (g_units) {
case TT_DAYS:
diff /= 86400l;
break;
case TT_HOURS:
diff /= 3600l;
break;
case TT_MINS:
diff /= 60l;
break;
case TT_WEEKS:
diff /= 604800l;
break;
case TT_MONTHS:
diff /= 2592000l;
break;
}
return (g_range < 0 ? diff < days :
g_range > 0 ? diff > days :
diff == days);
}
switch の条件のところにある g_unitsという変数もグローバル変数ですかね (引数にないし、いきなり参照しているし)。 funcに代入した関数ポインターをさらに 代入しているところをみるとこう
if (func) {
/* Requested test is performed by function func */
if (!qn)
qn = (struct qual *)hcalloc(sizeof *qn);
if (ql)
ql->next = qn;
ql = qn;
if (!newquals)
newquals = qo = qn;
qn->func = func;
qn->sense = sense;
qn->data = data;
qn->sdata = sdata;
qn->range = g_range;
qn->units = g_units;
qn->amc = g_amc;
qn = NULL;
qualct++;
}
func以外のdataやらsdataなどは実際に関数を呼び出すときの 引数のようだけど、g_range、g_units、g_amcを 構造体のメンバーに設定しているのは?
ということで関数ポインター経由で呼び出しているところは…と調べるとここか。
/* This may be set by qualifier functions to an array of strings to insert
* into the list instead of the original string. */
static char **inserts;
/* add a match to the list */
/**/
static void
insert(char *s, int checked)
{
struct stat buf, buf2, *bp;
char *news = s;
int statted = 0;
ちょっと長めの関数なので適当にすっとばして
for (qn = qo; qn && qn->func;) {
g_range = qn->range;
g_amc = qn->amc;
g_units = qn->units;
if ((qn->sense & 2) && !(statted & 2)) {
/* If (sense & 2), we're following links */
if (!S_ISLNK(buf.st_mode) || statfullpath(s, &buf2, 0))
memcpy(&buf2, &buf, sizeof(buf));
statted |= 2;
}
bp = (qn->sense & 2) ? &buf2 : &buf;
/* Reject the file if the function returned zero *
* and the sense was positive (sense&1 == 0), or *
* vice versa. */
if ((!((qn->func) (news, bp, qn->data, qn->sdata))
^ qn->sense) & 1) {
/* Try next alternative, or return if there are no more */
if (!(qo = qo->or)) {
unqueue_signals();
return;
}
qn = qo;
continue;
}
qn = qn->next;
}
ふむ。引数の数が足りない(ほかの関数と合わせるため?)のでグローバル変数持ち出している?
関数の引数を工夫すれば(qn->data, qn->sdata のように個々のメンバーを渡すのではなく、 構造体(へのポインター)を渡すとか)この辺の変数は使わずにすませられそうな気もするけど 他でもなにか使ってたりするのかな。