ときどきの雑記帖 RE* (新南口)
あたいの夏休み
Aliens
エイリアンも2が大好きだったりする。 もちろん1は1で好きなんだけど。
「パート2」好きなのかな、わし(笑)
リクエスト
プロ野球のアレ、なんで「リクエスト」なんつー よくわからない呼び方をしているのか 疑問に思ってちょっと調べてみた。
まずはうぃきぺ。
なお、この場合のチャレンジとは「挑戦」ではなく、「異議申し立て」を意味する[9]。
[9]のリンク先はこれ challengeの意味・使い方・読み方|英辞郎 on the WEB
MLBで導入されているチャレンジ方式については、12球団監督からの要望は多いものの「すべてをリプレーに頼るのは審判員の技術向上に逆行する」 と審判側の慎重な意見もあり、長らく導入には至っていなかった[21]。
しかし2018年シーズンより「監督が審判の判定に異議がある場合、ビデオ映像によるリプレー検証を求めることができる」 という新ルールが施行されることとなった。こちらのビデオ判定の名称は「チャレンジ」ではなく「リクエスト」となっている。
ふむ。しかしなぜ「リクエスト」になったのかはわからないので 脚注のリンク先などもみていくとこんなのが見つかった。
日本版「チャレンジ」の名称は『リクエスト』 1試合で失敗2度まで可能(2/7ページ) - サンスポ
「リクエスト」の名称は「(MLBの)チャレンジは挑発的な表現だが、あえてやわらかい表現にした」(江幡委員長)という。
は?
パー●ヴィアランス
サイエンスZEROの8/15放送回では 「パーシビアランス」って言ってたがそういうもんなんだろうかあの番組。
Perl
前回書き忘れた。 何が起きてるの一体。
- The Perl Foundation is fragmenting over Code of Conduct enforcement | Ars Technica
- Perl Foundation faces more departures after pausing Community Affairs Team • The Register
Python の hash
Pythonにはhash()という組み込み関数がありますが、上記動画によるとどうやら CPython においては戻り値が__hash__() の戻り値とは異なる事があるらしいです。試しに以下のcodeを実行してみると
というのが気になったのでちょっと調べてみた。
まずはここから。
cpython/object.c at main · python/cpython
Py_hash_t
PyObject_Hash(PyObject *v)
{
PyTypeObject *tp = Py_TYPE(v);
if (tp->tp_hash != NULL)
return (*tp->tp_hash)(v);
/* To keep to the general practice that inheriting
* solely from object in C code should work without
* an explicit call to PyType_Ready, we implicitly call
* PyType_Ready here and then check the tp_hash slot again
*/
if (tp->tp_dict == NULL) {
if (PyType_Ready(tp) < 0)
return -1;
if (tp->tp_hash != NULL)
return (*tp->tp_hash)(v);
}
/* Otherwise, the object can't be hashed */
return PyObject_HashNotImplemented(v);
}
なんかエラーが起きたときに-1を返しているっぽいようではあるけれども ここでは「すり替え」は行われていない。
別のオブジェクトを見ていくとたとえば cpython/interpreteridobject.c at bb3e0c240bc60fe08d332ff5955d54197f79751c · python/cpython では
static Py_hash_t
interpid_hash(PyObject *self)
{
interpid *id = (interpid *)self;
PyObject *obj = PyLong_FromLongLong(id->id);
if (obj == NULL) {
return -1;
}
Py_hash_t hash = PyObject_Hash(obj);
Py_DECREF(obj);
return hash;
}
ここでもエラー時の-1だけしか見当たらない。
めげずに見ていくと cpython/methodobject.c at bfc2d5a5c4550ab3a2fadeb9459b4bd948ff61a2 · python/cpython でようやく
static Py_hash_t
meth_hash(PyCFunctionObject *a)
{
Py_hash_t x, y;
x = _Py_HashPointer(a->m_self);
y = _Py_HashPointer((void*)(a->m_ml->ml_meth));
x ^= y;
if (x == -1)
x = -2;
return x;
}
おお、-1を-2にすり替えている。
ということで3.9.5のソースを対象に grep -r --include="*.c" -B 2 -e"= -2;"
を試したところ
./Modules/_sre.c-
./Modules/_sre.c- if (hash == -1) {
./Modules/_sre.c: hash = -2;
--
./Objects/bytesobject.c- else {
./Objects/bytesobject.c- arglen = -1;
./Objects/bytesobject.c: argidx = -2;
--
./Objects/bytesobject.c- args_owned = 1;
./Objects/bytesobject.c- arglen = -1;
./Objects/bytesobject.c: argidx = -2;
--
./Objects/classobject.c- x = x ^ y;
./Objects/classobject.c- if (x == -1)
./Objects/classobject.c: x = -2;
--
./Objects/classobject.c- x = x ^ y;
./Objects/classobject.c- if (x == -1)
./Objects/classobject.c: x = -2;
--
./Objects/codeobject.c- co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^
./Objects/codeobject.c- co->co_nlocals ^ co->co_flags;
./Objects/codeobject.c: if (h == -1) h = -2;
--
./Objects/descrobject.c- x = x ^ y;
./Objects/descrobject.c- if (x == -1)
./Objects/descrobject.c: x = -2;
--
./Objects/methodobject.c- x ^= y;
./Objects/methodobject.c- if (x == -1)
./Objects/methodobject.c: x = -2;
--
./Objects/typeobject.c- /* -1 is reserved for errors. */
./Objects/typeobject.c- if (h == -1)
./Objects/typeobject.c: h = -2;
--
./Objects/unicodeobject.c- ctx->args_owned = 1;
./Objects/unicodeobject.c- ctx->arglen = -1;
./Objects/unicodeobject.c: ctx->argidx = -2;
--
./Objects/unicodeobject.c- else {
./Objects/unicodeobject.c- ctx.arglen = -1;
./Objects/unicodeobject.c: ctx.argidx = -2;
--
./Python/initconfig.c- _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding);
./Python/initconfig.c- if (!_Py_StandardStreamEncoding) {
./Python/initconfig.c: res = -2;
--
./Python/pyhash.c- Py_hash_t x = _Py_HashPointerRaw(p);
./Python/pyhash.c- if (x == -1) {
./Python/pyhash.c: x = -2;
違うものもひっかっかったけど、なるほど。
コードだけではアレなので さらに見ていくと cpython/typeobj.rst at 10faada709561663d6b1f623d308ff45e3808cca · python/cpython にこういう記述があった。
.. c:member:: hashfunc PyTypeObject.tp_hash
.. index:: builtin: hash
An optional pointer to a function that implements the built-in function
:func:`hash`.
The signature is the same as for :c:func:`PyObject_Hash`::
Py_hash_t tp_hash(PyObject *);
The value ``-1`` should not be returned as a
normal return value; when an error occurs during the computation of the hash
value, the function should set an exception and return ``-1``.
When this field is not set (*and* :attr:`tp_richcompare` is not set),
an attempt to take the hash of the object raises :exc:`TypeError`.
This is the same as setting it to :c:func:`PyObject_HashNotImplemented`.
This field can be set explicitly to :c:func:`PyObject_HashNotImplemented` to
block inheritance of the hash method from a parent type. This is interpreted
as the equivalent of ``__hash__ = None`` at the Python level, causing
``isinstance(o, collections.Hashable)`` to correctly return ``False``. Note
that the converse is also true - setting ``__hash__ = None`` on a class at
the Python level will result in the ``tp_hash`` slot being set to
:c:func:`PyObject_HashNotImplemented`.
**Inheritance:**
Group: :attr:`tp_hash`, :attr:`tp_richcompare`
This field is inherited by subtypes together with
:c:member:`~PyTypeObject.tp_richcompare`: a subtype inherits both of
:c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash`, when the subtype's
:c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` are both ``NULL``.
cpython/3.2.rst at 11749e2dc20ad6a76e9a39e948853e89b2b4bbed · python/cpython
Hash values are now values of a new type, :c:type:
Py_hash_t
, which is defined to be the same size as a pointer. Previously they were of type long, which on some 64-bit operating systems is still only 32 bits long. As a result of this fix, :class:set
and :class:dict
can now hold more than 2**32 entries on builds with 64-bit pointers (previously, they could grow to that size but their performance degraded catastrophically).
xargs
毎度情報ありがとうございます。
Not only is the Internet dead, it’s starting to smell really bad.:2021年08月15日分
ところであの記事にはいくつか気になったことがあったので調べてみた。
ただし、-Jオプションには-Iオプションとの間に挙動の違いがありました。
以下のようにa{}bと置換文字列の前後に空白がない場合は認識されないようです。 a{}bがそのまま出力された上で、標準入力の文字列は末尾に展開されて出力されました。
echo foo | xargs -J {} echo a{}b
# a{}b foo
echo foo | xargs -I {} echo a{}b
# afoob
また、以下の通り、クォート内の置換文字列は-Jオプションでは認識されないようです。
It will not be recognized if, for instance, it is in the middle of a quoted string.
ユースケースとして、標準入力の値を使ってコマンドを構築して実行する場合、以下のような書き方をすることがあると思います。 -Iオプションでは想定通りの挙動を示すものの、-Jオプションでは上手くいきませんでした。
echo foo | xargs -J {} bash -c 'echo {}'
# {}
echo foo | xargs -I {} bash -c 'echo {}'
# foo
のように書かれていて、manからの出力の引用として
-J replstr
If this option is specified, xargs will use the data read from standard input to replace the first occurrence of replstr instead of appending that data after all other arguments. This option will not affect how many arguments will be read from input (-n), or the size of the command(s) xargs will generate (-s).
とあったのだけど、これで全部ではなく 引用から漏れたところに「きちんと」上記の動作を説明することが書かれていた。
MacのxargsのJ option (replacerを使う記法) - AllIsHackedOff にある、同じくmanの出力からの引用によれば
-J replstr If this option is specified, xargs will use the data read from standard input to replace the first occurrence of replstr instead of appending that data after all other arguments. This option will not affect how many arguments will be read from input (-n), or the size of the command(s) xargs will generate (-s). The option just moves where those arguments will be placed in the command(s) that are executed. The replstr must show up as a distinct argument to xargs. It will not be recognized if, for instance, it is in the middle of a quoted string. Furthermore, only the first occurrence of the replstr will be replaced. For example, the following command will copy the list of files and directories which start with an uppercase letter in the current directory to destdir:
/bin/ls -1d [A-Z]* | xargs -J % cp -rp % destdir
が全体で、あの記事の引用では
The replstr must show up as a distinct argument to xargs. It will not be recognized if, for instance, it is in the middle of a quoted string.
がすっぽり抜け落ちている。
echo foo | xargs -J {} echo a{}b
は
{}
が独立した引数になっていないからで、
echo foo | xargs -J {} bash -c 'echo {}'
は{}がクォートの中にあるから、ではなく
クォートで括られてecho
とひとまとまりになって
xargsに渡されているため。
だから、echo foo | xargs -J {} echo '{}'
は
クオートのなかに{}があるけれども置換が行われる(はず)。
というのがこれで明確になりました。と。
にしても探してみたらこの辺の話題に関して結構いろいろな記事が書かれてますな。
- GNU版, BSD版 xargsの挙動の違い - syohex’s diary
- GNU/BSDでのxargsの振る舞いの違い
- BSD系xargsのunterminated quoteとオマケ - by shigemk2
- xargs が Linux と Mac 両方できちんと動くためには -i ではなく -I オプションを使う - blog.ayakumo.net
- コマンド:xargs: UNIX/Linuxの部屋
- xargs ナニモワカラナイ - Neo’s World
- Macでfind -type f | xargs grepと同じことができないか検証してみた | Masyus Work
- LinuxのコマンドはMacOSXでそのまま動くとは限らない - Blank?=False
- GNU/BSDでのxargsの振る舞いの違い
- xargs(1) FreeBSDドキュメントJMan
- xargs(1)
ソースコードもいろいろ読み比べたのだけど その詳細はまたの機会に。
- findutils/xargs.c at r4.4.2-aix · aixoss/findutils
- freebsd-src/usr.bin/xargs at main ・ freebsd/freebsd-src
- freebsd-src/xargs.c at main · freebsd/freebsd-src
- V10/cmd/xargs.c
printf
ところで
printf x"%.s" {1..255} | xargs -I {} echo {}
というprintfコマンド(この場合はbashのビルトイン?)の 使い方が気になって