■_
日没の時刻が早くなってきて、会社帰りに無灯火の自転車に遭遇する頻度が上昇中。
一つ前へ
2014年9月(中旬)
一つ後へ
2014年10月(上旬)
日没の時刻が早くなってきて、会社帰りに無灯火の自転車に遭遇する頻度が上昇中。
Perl's Problems - Perl Hacks Perl’s Problems 28 September, 2014Programmingperl, problems, usage It’s been over six weeks since I wrote my blog post on Perl usage. I really didn’t mean to leave it so long to write the follow-up. But real life intervened and I haven’t had time for much blogging. That’s still the case (I should be writing a talk right now) but I thought it was worth jotting down some quick notes about what I think is causing Perl’s decline. Reputation (略) Complexity A lot of Perl’s reputation as executable line noise is completely unwarranted. The people who were writing those 1990s balls of mud were under such pressure to deliver that they would have almost certainly delivered something just as unmaintainable whatever language they were using. But some of that reputation is fair. I’ve been teaching Perl for almost fifteen years and I know that there are some parts of Perl that people find confusing. Here are some examples:
で、挙げられた項目が
Sigils Context Data Structures
この三つ(それぞれの詳細(特に三つめ)は原文でよろしく)。 んー sigils 好きなんだけどなあ。
イカサマータイム期間終わって今日から元の時間帯に。 とはいえ微妙に電車が混むんだよなあ(座れるか座れないか五分五分くらい)。
2015年のカレンダーが売られる時期に。
ということでこれを手配。
デザインフィル ミドリ 2015年版フラットダイアリーライト 黒 2014年10月始まり A4 27365006
デザインフィル ミドリ 2015年版フラットダイアリーライト 黒 2014年10月始まり A5 27362006
This package contains the compiler and set of system headers necessary for producing binary wheels for Python 2.7 packages.
珠玉のプログラミングの訳ってどうだったっけか。 とはいえ、あれ原著の版も上がっているのではなかったっけ。
「プログラミング20言語習得法」の話題をいまごろ知ったのですけど、そもそもこの人の「珠玉のプログラミング」の訳がきらいで、前の版の「プログラム設計の着想」が好きでした。
— こはらー (@takashi_kohara) 2014, 9月 27
Programming Pearls (ACM Press)
More Programming Pearls: Confessions of a Coder (ACM Press)
Programming Pearls (ACM Press)
InfoQ だし訳されるだろうけども。 ShellShocked - Behind the Bug
ShellShocked - Behind the Bug (略) The problem occurs because a feature (not a bug?) in the Bash shell allows functions to be defined in environment variables. Functions allow commonly called code to be defined and then re-used in later places, and are available in all shell script languages. Functions in Bash (and most other shells) can be defined as follows: function hello { echo "Hello" } hello # call the function However, Bash also has a means to define a function using environment variables, which is unique to Bash. An environment variable whose value starts with the characters (){ is treated as an implicitly imported function definition, which takes only takes effect on shell start-up: $ export HELLO="() { echo 'Hello'; }" $ HELLO -bash: HELLO: command not found $ bash $ HELLO Hello Because it only takes effect at shell start-up, most of the examples demonstrating the vulnerability have been one-liners of the form: env HELLO="() { echo 'Hello'; }" bash -c HELLO which does the same thing as the above. (The env command says 'run the following program with this environment variable set' in a portable way; in fact, HELLO="() { echo 'Hello'; }" bash -c HELLO works just as well.) The one-line bash command (specified with -c) is then necessary to show the execution, which has to be in a new shell since it is only parsed at start-up. (略) Note that the bug didn't affect just CGI scripts and Apache — if variables were poisoned in a similar way to other programs that pass values through (such as ssh with variables like TERM or DISPLAY) and those processes ran a Bash script (or implicitly executed them with system() calls) then the same vulnerability could be exploited. Unlike HTTP the requests cannot be made anonymously — a login is required to be able to trigger it — but with code hosting providers allowing free log-on (even to a restricted shell) GitHub provided updates for its enterprise product and Bitbucket updated its servers to remediate against any possible incursion. 以降 7169 の方にも言及しているけど略
なるほどよくわかった(気がする)。 お祭り状態で色々検証やらなんやらやってた記事は幾つもあったけど この辺きちんと書いたのはあったのかなあ。
ここで取りあげられている元記事を見てみたら John Carmack email on inlined code and functional programming : programming
Jonathan Blow's home page >Indeed, if memory serves (it's been a while since I read about this)... > >The fly-by-wire flight software for the Saab Gripen (a lightweight >fighter) went a step further. It disallowed both subroutine calls and >backward branches, except for the one at the bottom of the main loop. >Control flow went forward only. Sometimes one piece of code had to leave >a note for a later piece telling it what to do, but this worked out well >for testing: all data was allocated statically, and monitoring those >variables gave a clear picture of most everything the software was doing. >The software did only the bare essentials, and of course, they were >serious about thorough ground testing. > >No bug has ever been found in the "released for flight" versions of that >code. > > Henry Spencer > henry@spsystems.net
Henry Spencer のお名前が。
variable.c は先にちょっと読んでたけど ↓ のツイートを見て検索したら 問題のリテラルがまんまif の条件式のところにあって大笑い。
詳しく見たい人はvariable.cを"() {"で検索して前後を読むといいです。パッチはparse_and_execute()に、関数定義のみ&マルチステートメント禁止で解釈するという機能を加えようとしたようだけど、場当たり的にやると穴が残りそう…というかもう穴が指摘されてる。
— 上原 哲太郎 (@tetsutalow) 2014, 9月 25
じーかーんがーなーいー
TODO: 日経Linux を買う
一度は行ってみたいなあ Strange Loop 2014 - Julia Evans
面白かった(が、結論は面白くないかも) Rosetta Code Analysis
wikipedia にエントリ作られてるとは知らなかった 2009–11 Toyota vehicle recalls - Wikipedia, the free encyclopedia
そしてこれ。 reddit でこの話題が出てたので何でまた今頃と思ったのだけど、 最近またなんか発表してたのね。 新しい情報はなさげ? A Case Study of Toyota Unintended Acceleration and Software Safety : programming
宇宙博2014行くの忘れたー
大江戸と違ってあえて東をえらんでいるわけではないです!
シェルを作成しています。 昔kshを作ってたので、ksh+awkでCSVファイル処理をしたいのですが、
最後(たぶん)
freadseek.c /* Skipping input from a FILE stream. Copyright (C) 2007-2014 Free Software Foundation, Inc. (略) /* Increment the in-memory pointer. INCREMENT must be at most the buffer size returned by freadptr(). This is very cheap (no system calls). */ static void freadptrinc (FILE *fp, size_t increment) { /* Keep this code in sync with freadptr! */ #if HAVE___FREADPTRINC /* musl libc */ __freadptrinc (fp, increment); #elif defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ fp->_IO_read_ptr += increment; #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin */ fp_->_p += increment; fp_->_r -= increment; #elif defined __EMX__ /* emx+gcc */ fp->_ptr += increment; fp->_rcount -= increment; #elif defined __minix /* Minix */ fp_->_ptr += increment; fp_->_count -= increment; #elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */ fp_->_ptr += increment; fp_->_cnt -= increment; #elif defined __UCLIBC__ /* uClibc */ # ifdef __STDIO_BUFFERS fp->__bufpos += increment; # else abort (); # endif #elif defined __QNX__ /* QNX */ fp->_Next += increment; #elif defined __MINT__ /* Atari FreeMiNT */ fp->__bufp += increment; #elif defined EPLAN9 /* Plan9 */ fp->rp += increment; #elif defined SLOW_BUT_NO_HACKS /* users can define this */ #else #error "Please port gnulib freadseek.c to your platform! Look at the definition of getc, getc_unlocked on your system, then report this to bug-gnulib." #endif } int freadseek (FILE *fp, size_t offset) { size_t total_buffered; int fd; if (offset == 0) return 0; /* Seek over the already read and buffered input as quickly as possible, without doing any system calls. */ total_buffered = freadahead (fp); /* This loop is usually executed at most twice: once for ungetc buffer (if present) and once for the main buffer. */ while (total_buffered > 0) { size_t buffered; if (freadptr (fp, &buffered) != NULL && buffered > 0) { size_t increment = (buffered < offset ? buffered : offset); freadptrinc (fp, increment); offset -= increment; if (offset == 0) return 0; total_buffered -= increment; if (total_buffered == 0) break; } /* Read one byte. If we were reading from the ungetc buffer, this switches the stream back to the main buffer. */ if (fgetc (fp) == EOF) goto eof; offset--; if (offset == 0) return 0; total_buffered--; } /* Test whether the stream is seekable or not. */ (略) eof: /* EOF, or error before or while reading. */ if (ferror (fp)) return EOF; else /* Encountered EOF. */ return 0; }
freadprt.c /* Retrieve information about a FILE stream. Copyright (C) 2007-2014 Free Software Foundation, Inc. (略) const char * freadptr (FILE *fp, size_t *sizep) { size_t size; /* Keep this code in sync with freadahead! */ #if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ if (fp->_IO_write_ptr > fp->_IO_write_base) return NULL; size = fp->_IO_read_end - fp->_IO_read_ptr; if (size == 0) return NULL; *sizep = size; return (const char *) fp->_IO_read_ptr; #elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin */ if ((fp_->_flags & __SWR) != 0 || fp_->_r < 0) return NULL; size = fp_->_r; if (size == 0) return NULL; *sizep = size; return (const char *) fp_->_p; (略) #elif defined SLOW_BUT_NO_HACKS /* users can define this */ /* This implementation is correct on any ANSI C platform. It is just awfully slow. */ return NULL; #else #error "Please port gnulib freadptr.c to your platform! Look at the definition of fflush, fread, getc, getc_unlocked on your system, then report this to bug-gnulib." #endif }
ということで、cut が gawk より遅い云々はたぶんこの辺りが原因。 gawk はたしかバッファ一杯にごそっと読み込んでからレコードを切り出して、 それからごにょごにょやってるから。 あと、出力のときにもフィールド指定の具合によっては一バイトずつ読んでは…というのをやってたような。
毒吐こうかなあと考えたけど思い直して止めた
Ruby Under a Microscope: An Illustrated Guide to Ruby Internals
で、これを貼り付けるとこの本を腐そうとしたようにとられるかな?
違うよ?
あ、先越された 「制限だらけで何も出来ない公園」に行ってみたら、商業施設の敷地内だった - akiyan.com
いけね。 A Case Study of Toyota Unintended Acceleration and Software Safety : programming これのリンク先のPDF読むの忘れてた
つづき。cut.c で呼び出していた getdeim2 について
getdelim.c /* getndelim2 - Read a line from a stream, stopping at one of 2 delimiters, with bounded memory allocation. (略) /* The maximum value that getndelim2 can return without suffering from overflow problems, either internally (because of pointer subtraction overflow) or due to the API (because of ssize_t). */ #define GETNDELIM2_MAXIMUM (PTRDIFF_MAX < SSIZE_MAX ? PTRDIFF_MAX : SSIZE_MAX) /* Try to add at least this many bytes when extending the buffer. MIN_CHUNK must be no greater than GETNDELIM2_MAXIMUM. */ #define MIN_CHUNK 64 ssize_t getndelim2 (char **lineptr, size_t *linesize, size_t offset, size_t nmax, int delim1, int delim2, FILE *stream) { size_t nbytes_avail; /* Allocated but unused bytes in *LINEPTR. */ char *read_pos; /* Where we're reading into *LINEPTR. */ ssize_t bytes_stored = -1; char *ptr = *lineptr; size_t size = *linesize; bool found_delimiter; if (!ptr) { size = nmax < MIN_CHUNK ? nmax : MIN_CHUNK; ptr = malloc (size); if (!ptr) return -1; } if (size < offset) goto done; nbytes_avail = size - offset; read_pos = ptr + offset; if (nbytes_avail == 0 && nmax <= size) goto done; /* Normalize delimiters, since memchr2 doesn't handle EOF. */ if (delim1 == EOF) delim1 = delim2; else if (delim2 == EOF) delim2 = delim1; flockfile (stream); found_delimiter = false; do { /* Here always ptr + size == read_pos + nbytes_avail. Also nbytes_avail > 0 || size < nmax. */ int c IF_LINT (= 0); const char *buffer; size_t buffer_len; buffer = freadptr (stream, &buffer_len); if (buffer) { if (delim1 != EOF) { const char *end = memchr2 (buffer, delim1, delim2, buffer_len); if (end) { buffer_len = end - buffer + 1; found_delimiter = true; } } } else { c = getc (stream); if (c == EOF) { /* Return partial line, if any. */ if (read_pos == ptr) goto unlock_done; else break; } if (c == delim1 || c == delim2) found_delimiter = true; buffer_len = 1; } /* We always want at least one byte left in the buffer, since we always (unless we get an error while reading the first byte) NUL-terminate the line buffer. */ (略) if (buffer && freadseek (stream, buffer_len)) goto unlock_done; } while (!found_delimiter); /* Done - NUL terminate and return the number of bytes read. At this point we know that nbytes_avail >= 1. */ *read_pos = '\0'; bytes_stored = read_pos - (ptr + offset); unlock_done: funlockfile (stream); done: *lineptr = ptr; *linesize = size; return bytes_stored ? bytes_stored : -1; }
freadaptr と freadseek ってのはこれまた別のファイルにある関数。 んでまあそこは飛ばしてこの関数がどういったものかはここに書かれている
getdelim2.h /* getndelim2 - Read a line from a stream, stopping at one of 2 delimiters, with bounded memory allocation. (略) /* Read into a buffer *LINEPTR returned from malloc (or NULL), pointing to *LINESIZE bytes of space. Store the input bytes starting at *LINEPTR + OFFSET, and null-terminate them. Reallocate the buffer as necessary, but if NMAX is not GETNLINE_NO_LIMIT then do not allocate more than NMAX bytes; if the line is longer than that, read and discard the extra bytes. Stop reading after the first occurrence of DELIM1 or DELIM2, whichever comes first; a delimiter equal to EOF stands for no delimiter. Read the input bytes from STREAM. Return the number of bytes read and stored at *LINEPTR + OFFSET (not including the NUL terminator), or -1 on error or EOF. */ extern ssize_t getndelim2 (char **lineptr, size_t *linesize, size_t offset, size_t nmax, int delim1, int delim2, FILE *stream); #endif /* GETNDELIM2_H */
続く。のか?
というわけでこの著者の他の本をチェックすると… Amazon.co.jp: 小林 健一郎: 本 翻訳本はともかく自著はなんと言うかその…ごにょごにょ
『プログラミング20言語習得法』 初心者のための実践独習ガイド 小林健一郎=著 | ブルーバックス前書き図書館 | 現代ビジネス [講談社] にもこの本の内容について書かれていますが
『プログラミング20言語習得法』 初心者のための実践独習ガイド 小林健一郎=著 | ブルーバックス前書き図書館 | 現代ビジネス [講談社] ★取り上げている言語: C C++ Java Perl Visual Basic FORTRAN BASIC Pascal Ada Objective-C C# COBOL LISP(Common Lisp, Racket) Haskell Scala Python Ruby VBScript Smalltalk AWK Java Script PHP
という部分があります。 目次によると最初の5個(C, C++, Java, Perl, Visual Basic)は 「プログラムの世界の潮流がわかる主要5言語」で、残りは 「さらに知っておきたい特色ある15言語」 なんだそうです。
プログラミング言語の紹介で短いサンプルプログラムが結構載っているのですが このプログラムがまた何とも言い難いものだったりします。 たとえば Perl。
open(IN, "eng.txt"); @x = <IN> close(IN); @y = sort(@x); print @y;
$x = int(rand(3)); if ($x == 0) { print "大吉です\n": } elsif ($x == 1) { print "普通です\n"; } else { print "凶です\n"; }
…えーと。
他にも Ruby の紹介のところでは(p.258)
ただし、日本語を表示したい場合、「日本語の文字コード」(251ページのコラムを参照)を 指定する必要があります。たとえば、シフトJIS方式を使っている場合、実行は、 ruby -Ks hello.rb で行うことができます。また、EUC-JP なら -Ks ではなく -Ke、UTF-8 なら -Ku とします。
なんてのがあったり。 好意的に解釈すれば、Perl にしても Ruby にしても古いバージョンを使う場合を 考慮したと言えるかもしれないけど、ちょっとなあ。
Pascal では gpc を使っていますが、 gcc とのバージョンあわせ云々とか書くくらいなら (というか gpc 今メンテされないの?) FreePascal 使えばいいと思うんですけどね。 あー、Ada (GNAT)、Objective-C (GCCのやつ) を使いたいからか。 にしたってなあ…
面倒になったのでここで終わり。
rubykaigi2014のはなし。 「ホールでの飲食禁止」ってのが散々アナウンスされてたのだけど、 ひじょーに目立つ外見のお方がバッグに何本もペットボトルの飲料を持ってて、数分と開けず口にしてた (直接見てたのは初日の午前中だけだけど、三日ともそうだったっぽい)。 さすがに空の容器は持って帰ってたぽいけど、ああいうのは見かけたときに注意すべきだったんだろうか。 それとも近くにいるスタッフの人に伝える?
もうひとつ書いておくと、 休憩時間の音楽の音量がちょーーーーっと大きな気がしたんだけど (音量に関して)なにか目安みたいなものはあるんだろか。 たぶん自分が過敏になってるせいだとは思うんだけど 正直ちょっと辛かったのよ。
Ruby嫌いがアンダースタンディングコンピュテーションを読んで - ぐるぐる~ で、
6.1.4 何か所か原文を確認したくなったところはありましたが、とても少ないです。 意味がよく分からないな、と思った個所は 一つだけです。 P.169に、 ブール値を将来のコードが読める決まったデータとして考えるのではなく、2つの選択肢を引数として呼び出し、1番目 と2番目の選択肢のどちらかを選ぶコードとして、直接的に実装しましょう。 とありますが、この前半部分の意味が分かりませんでした。 ただ、ここが分からなくても後半部分だけで実際にやりたい ことはわかるため、それほど問題とも思いませんでした。
この辺を原著からちょっと広めに。
Booleans How can we represent Booleans using only procs? Well, Booleans exist solely to be used in conditional statements, and in general, a conditional says “if some Boolean then this else that”: >> success = true => true >> if success then 'happy' else 'sad' end => "happy" >> success = false => false >> if success then 'happy' else 'sad' end => "sad" So the real job of a Boolean is to allow us to choose between two options, and we can take advantage of this by representing a Boolean as a proc that chooses one of two values. Instead of thinking of a Boolean as a lifeless piece of data that can be read by some future code to decide which of two options to choose, we’ll just implement it directly as a piece of code that, when called with two options, either chooses the first option or chooses the second option. Implemented as methods, then, #true and #false could be: def true(x, y) x end def false(x, y) y end
TaPL でやったわーw > represent Booleans using only procs
ま、それはさておき
Instead of thinking of a Boolaen ~ のとことですかね。ふむ。
元記事読み返したらコメントに原文ついてた
ということで GNU coreutils の cut のソース読んだよ!(駆け足で)
/* cut - remove parts of lines of files Copyright (C) 1997-2014 Free Software Foundation, Inc. Copyright (C) 1984 David M. Ihnat This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* Written by David Ihnat. */ /* POSIX changes, bug fixes, long-named options, and cleanup by David MacKenzie <djm@gnu.ai.mit.edu>. Rewrite cut_fields and cut_bytes -- Jim Meyering. */
一番に怪しいのは入力のところだよなあ。で、
/* Read from stream STREAM, printing to standard output any selected bytes. */ static void cut_bytes (FILE *stream)
こっちはスルーして
/* Read from stream STREAM, printing to standard output any selected fields. */ static void cut_fields (FILE *stream) { int c; size_t field_idx = 1; bool found_any_selected_field = false; bool buffer_first_field; current_rp = rp; c = getc (stream); if (c == EOF) return; ungetc (c, stream); c = 0; /* To support the semantics of the -s flag, we may have to buffer all of the first field to determine whether it is 'delimited.' But that is unnecessary if all non-delimited lines must be printed and the first field has been selected, or if non-delimited lines must be suppressed and the first field has *not* been selected. That is because a non-delimited line has exactly one field. */ buffer_first_field = (suppress_non_delimited ^ !print_kth (1)); while (1) { if (field_idx == 1 && buffer_first_field) { ssize_t len; size_t n_bytes; len = getndelim2 (&field_1_buffer, &field_1_bufsize, 0, GETNLINE_NO_LIMIT, delim, '\n', stream); if (len < 0) { free (field_1_buffer); field_1_buffer = NULL; if (ferror (stream) || feof (stream)) break; xalloc_die (); } n_bytes = len; assert (n_bytes != 0); c = 0; /* If the first field extends to the end of line (it is not delimited) and we are printing all non-delimited lines, print this one. */ if (to_uchar (field_1_buffer[n_bytes - 1]) != delim) { if (suppress_non_delimited) { /* Empty. */ } else { fwrite (field_1_buffer, sizeof (char), n_bytes, stdout); /* Make sure the output line is newline terminated. */ if (field_1_buffer[n_bytes - 1] != '\n') putchar ('\n'); c = '\n'; } continue; } if (print_kth (1)) { /* Print the field, but not the trailing delimiter. */ fwrite (field_1_buffer, sizeof (char), n_bytes - 1, stdout); /* With -d$'\n' don't treat the last '\n' as a delimiter. */ if (delim == '\n') { int last_c = getc (stream); if (last_c != EOF) { ungetc (last_c, stream); found_any_selected_field = true; } } else found_any_selected_field = true; } next_item (&field_idx); } int prev_c = c; if (print_kth (field_idx)) { if (found_any_selected_field) { fwrite (output_delimiter_string, sizeof (char), output_delimiter_length, stdout); } found_any_selected_field = true; while ((c = getc (stream)) != delim && c != '\n' && c != EOF) { putchar (c); prev_c = c; } } else { while ((c = getc (stream)) != delim && c != '\n' && c != EOF) { prev_c = c; } } /* With -d$'\n' don't treat the last '\n' as a delimiter. */ if (delim == '\n' && c == delim) { int last_c = getc (stream); if (last_c != EOF) ungetc (last_c, stream); else c = last_c; } if (c == delim) next_item (&field_idx); else if (c == '\n' || c == EOF) { if (found_any_selected_field || !(suppress_non_delimited && field_idx == 1)) { if (c == '\n' || prev_c != '\n' || delim == '\n') putchar ('\n'); } if (c == EOF) break; field_idx = 1; current_rp = rp; found_any_selected_field = false; } } }
んー、getc 使って読んでるのが引っかかるなあ。 getndelim2 でも読み込みやってるぽいけどこれは cut.c にはない関数。 でもまあそもそもどのくらい gawk と cut で変わってくるのか 具体的な数字出して欲しかったわねえ(計測計測)…
一つ前へ
2014年9月(中旬)
一つ後へ
2014年10月(上旬)
リンクはご自由にどうぞ
メールの宛先はこちら