読者です 読者をやめる 読者になる 読者になる

agでファイル出力時もterminalと同じように閲覧したい

agことthe_silver_searcherをterminal上で使用した場合以下のような形式で出力されます

ag isatty
src/options.c
355:    if (!isatty(fileno(stdout))) {

src/print_w32.c
50:        !isatty(fileno(fp)) ||

これをファイルなどに書き込んだ場合、ファイルパスが先頭についた形で出力されます。

src/options.c:355:    if (!isatty(fileno(stdout))) {
src/print_w32.c:50:        !isatty(fileno(fp)) ||

これは出力先がterminalかどうかをisattyで判定しているので起きているのですが

351     /* If we're not outputting to a terminal. change output to:
352         * turn off colors
353         * print filenames on every line
354      */
355     if (!isatty(fileno(stdout))) {

terminalで見てる感じでファイルにも出力したいよねという感じでラーメン好きな人に相談したら

ag --heading --numbers isatty

こちらのオプションで似たような出力を得ることができました。

src/options.c
355:    if (!isatty(fileno(stdout))) {

src/print_w32.c
50:        !isatty(fileno(fp)) ||

便利ですね。

なお、こちらで使用されたagは以下のバージョンを使用しております

ag --version
ag version 1.0.2

Features:
  +jit +lzma +zlib

Goで読んだ本-とある同僚からの相談

この記事は Go (その2) Advent Calendar 2016 - Qiita の 18 日目の記事です。

Goを始めるにあたり、皆様はどうしているでしょうか?

などを見て始める方がいらっしゃる一方、 本を手にとって始めて見る方も一定数いらっしゃるかと思います。やはり日本語で書かれていること、本を書かれた方の知見などが得られるのは大きいのではないでしょうか。ここ最近、日本でもGoが流行っているせいか割と多くの本が出版されています。 私も本を読むのが好きなせいもあり、出版されて目立つ物は買って読んでいました。 自分よりその分野に詳しい人が、本を書くという過程で不要な情報をそぎ落とし精製された文章は読んでいてとても楽しいです。そんな感じで本が好きなので、同僚に「どの本がおすすめ?」なんて聞かれるのは割と楽しいわけです。そう言う場合、相手は同僚なのでスキル傾向とかやりたいこととかある程度分かっているので、

  • 入門じゃ無くてもうちょい深いところを知っときたい
  • Windowsで動かす予定があるのでその辺の知識が欲しい
  • 並列周り知りたい

という事前情報がありました。

もうちょい深くということで、

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

Windows対応と言うことで、

みんなのGo言語【現場で使える実践テクニック】

みんなのGo言語【現場で使える実践テクニック】

並列周りということで、

WEB+DB PRESS Vol.95

WEB+DB PRESS Vol.95

をおすすめしたんですが、 「僕の小遣いじゃ、全部は辛いすね。」 というお返事がかえってきまして、うーん。そういう事情もありますよね。そうなると、この中で一番コスパが良い「プログラミング言語Go」をおすすめしました。( 460pあって4000円ぐらいのお値段はお得ですよ。

  • Goの機能について一通り紹介している

- 特に以下は読むまで詳しく知らなかった
- forによる文字列連結のコスト
- UnicodeUTF-8の話
- 定数生成器 iota
- 構造体埋め込みと無名フィールド
- 無名関数のところにあるループ変数の捕捉
- 構造体埋め込みによる型の合成

  • 並行処理も2章さかれていて分かりやすい
  • Cとの接続方法であるcgoの使い方も書かれています

あと、大きなポイントと言えば ブライアン・カーニハンが書いてるのと、 割と大きな声で、「読んだ本?プログラミング言語Go読みましたよ。」って言える。ということろでしょうか。

ただ、個人的には他の2冊もお金が許すならおすすめです。

  • みんなのGo

- 言語を軽く学んだ後、次にやるべきコトが列挙されている
- 著者が活発に開発されている方が多いので経験からくるもので信頼できる
- 一般的な開発などをよく知らない人にはかなりお勧め
- マルチプラットフォームで動作する社内ツールのつくり方 は余り知る機会がすくないのでいい
- The Dark Arts Of Reflections 不可能を可能にする黒魔術 はこの手の黒魔術は知っておくとちょっと上達した気になれるのでいい

  • WEB+DB PRESS Vol.95 特集2 Goによる並行処理 複雑な処理をスイスイ書こう!

- マルチプロセスとマルチスレッド方式という、これまでの並列処理についての特徴などを解説していて並列処理どうしたらいいのてきな人におすすめ
- 美味しいのは、著者のpecoというツールを作る過程で得られた知見とpecoについて詳しく書かれている点です。


クリスマスですし、年末年始の長期休暇にも突入しますし、読んでない方いらっしゃいましたらこれを機会に読んでみられてはいかがでしょうか。

言語間に寄るsplitの仕様の差異

たまたま、goで書かれた物をperlへ移植しようとしていたらsplitの挙動の差が出てきまして、他の言語の場合どうなるんだろうとぱっと思いついた言語で実行して見ました。以下の文字列を言語標準でついている文字列のsplitを実行した結果となります。

"/path/to/hoge/"
言語 結果
perl(5.12) ['','path','to','hoge']
golang(1.5) ["" "path" "to" "hoge" ""]
ruby(2.1) ["", "path", "to", "hoge"]
ptyhon(2.7.8) ['', 'path', 'to', 'hoge', '']
js [ '', 'path', 'to', 'hoge', '' ]
perl6 ("", "path", "to", "hoge", "") # (perl6-m -e 'say "/path/to/hoge/".split("/").perl')
clojure(1.4.0) ["" "path" "to" "hoge"]
php(5.5.14) [0] => [1] => path [2] => to [3] => hoge

単純にsplitをした結果、末尾の扱いに差異が見られました。


言語の樹形図を遡っていけばなんか分かるのですかね。


http://gigazine.net/news/20070126_computer_languages_history/

追記

結果の例の字がtypoしてました。これは、言語別に試したときにtypoしていたようです。

node-nopasteを作りました

npm installで手軽に入るnopasteが欲しかったので作ってみました。

  1. npm installでよほどnodeのバージョンが古くない限りは入るはずです。
  2. defaultの挙動がonmemoryなのでserverを落とすとそのままデータが消えます。
    1. nopaste本来の役割が一時的なデータの保存であるという意味合いがあるのでこうなっています。
    2. 永続化を希望する場合は、redisを立ち上げて環境変数からredisを指定してください。

www.npmjs.com

npm install node-nopaste

まだ0.0.1なので改善したいところなどありますが
ちまちまアップデートしていこうかと考えています。

hubot-karma-simple version up 0.1.4 and bug fix

先日npmにあげたhubot-karma-simpleですが再起動でデータが消える挙動が有りましたのでversion0.1.4にて修正いたしました。

www.npmjs.com

hubot-karma-simpleを作成しました

最近はbotを作るときはhubotというフレームワークを使用するのが一般的らしいです。例にも漏れず私の周りでもhubotを使用するようになりまして、独自実装されていたbotで泳いでいたkarma botもお役御免になったのですが新しく投入されたkarmaさんが従来型に対して色々欲しい機能が足りていなくて作ることに相成りました。(ただ、基本white list方式でこの手のbotを作成するのはどこに設置されるかわからないのである意味正しい判断だと思います)ちっちゃいコミュニティで、それなりにhubotいじれる人がいて育成していけるなら、対象をblack list方式で管理した方が楽しいと考えて作成しました。version0.1.0なのでまだ書き直したいところとか不足している機能等はありますが徐々に直していこうかと考えています。

npm,githubに登録してあります。


www.npmjs.com


github.com


インストール方法はnpmの方のページをご参照いただければおわかりいただけるかと思います。

特徴

  1. 発言内での複数の++,--へ対応しております
  2. 環境変数からコマンドの使用を制御することが可能です
  3. 環境変数からmessageとthingのblack listを制御する正規表現を投入することが可能です
  4. コマンドからalias,black_list,increment_message,decrement_messageを追加削除することが可能です

使用例

環境変数から各種コマンドを使用するかしないかの選択が可能です。

export HUBOT_KARUMA_SIMPLE_USE_COMMAND_INCREMENT_MESSAGE=1

各種コマンド

@hubot karma-simple increment_message 。゚ヽ(゚´Д`)ノ゚。
add increment_message 。゚ヽ(゚´Д`)ノ゚。

@hubot karma-simple alias @yourid yourid
add @yourid alias yourid

詳細はnpmjsの方を見ていただけるとおわかりいただけるかと思います。

参照

実装に当たり、hubotの全ソースコードcoffeescriptのリファレンス, karma,plusplus script等を参照させていただきました。

  1. https://hubot.github.com/
  2. https://github.com/github/hubot
  3. http://coffeescript.org/
  4. https://github.com/github/hubot-scripts
  5. https://github.com/ajacksified/hubot-plusplus

URI::QueryParamのquery_paramよりquery_param_appendを使用した方がいい理由について

URI::QueryParam - Additional query methods for URIs

https://metacpan.org/pod/URI::QueryParam

perlにはURI::QueryParamというモジュールがありまして、URIモジュールだけだと
届かない痒いところに手が届くことをしてくれるモジュールです。

例えば、uriから特定のパラメータだけを削りたいとかそういう場合
URIだけだと面倒なんですが、URI::QueryParamがあれば割と簡単に消せます。

# uri_query.pl
use strict;
use warnings;
use URI;
use URI::QueryParam;

my $uri = URI->new('http://google.com/');
$uri->query_form( a => 1 );
warn $uri->as_string;
$uri->query_param_delete('a');
warn $uri->as_string;
http://google.com/?a=1 at uri_query.pl line 8.
http://google.com/ at uri_query.pl line 10.

その逆の追加もよろしくやってくれて
同一パラメータでもちゃんと追加対象にしてくれています。

# uri_query.pl
use strict;
use warnings;
use URI;
use URI::QueryParam;

my $uri = URI->new('http://google.com/');
$uri->query_form( a => 1 );
warn $uri->as_string;
$uri->query_param_append( a => 1 );
warn $uri->as_string;
http://google.com/?a=1 at uri_query.pl line 8.
http://google.com/?a=1&a=1 at uri_query.pl line 10.

問題は初期化時にどうすべきか?
ということでして、通常であればこういう感じにしてあげれば
メソッドの利用目的にも合っているのではないかと思うのですが、

# uri_query.pl
use strict;
use warnings;
use URI;
use URI::QueryParam;

sub add_default_param {
   my $uri = URI->new(shift);
   $uri->query_param_append( a => 1 );
   $uri->query_param_append( b => 1 );
   $uri->as_string;
}

warn add_uri_param('http://google.com/?hoge=1');

条件

  1. 渡される引数が想定可能であり、
  2. なおかつ同一パラメーターが無い

query_paramとどちらをおすすめすべきか?を定量的に返したい。

  1. 想定できない場合においてはquery_param_appendが正しいはず。
  2. 一応運用上の問題点を挙げるなら、安易にまねされるケースがあり得るなどがあげられます。
  3. とりあえずそこを無視した場合にquery_param_appendを推奨するに足る根拠が欲しい。
use strict;
use warnings;
use Benchmark qw(:all);
use URI;
use URI::QueryParam;

my $count = 100000;

timethese($count, {
   query_param        => sub {
         my $uri = URI->new('http://google.com/');
         $uri->query_param( a => 1 );
         $uri->query_param( b => 1 );
         $uri->query_param( c => 1 );
         $uri->query_param( d => 1 );
         $uri->query_param( f => 1 );
         $uri->as_string;
   },
   query_param_append => sub {
      my $uri = URI->new('http://google.com/');
      $uri->query_param_append( a => 1 );
      $uri->query_param_append( b => 1 );
      $uri->query_param_append( c => 1 );
      $uri->query_param_append( d => 1 );
      $uri->query_param_append( f => 1 );
      $uri->as_string;
   },
});

とりあえず、2回ほど試してみた。

Benchmark: timing 100000 iterations of query_param, query_param_append...
query_param: 17 wallclock secs (17.43 usr +  0.00 sys = 17.43 CPU) @ 5737.23/s (n=100000)
query_param_append: 14 wallclock secs (13.20 usr +  0.00 sys = 13.20 CPU) @ 7575.76/s (n=100000)

Benchmark: timing 100000 iterations of query_param, query_param_append...
query_param: 19 wallclock secs (18.46 usr +  0.00 sys = 18.46 CPU) @ 5417.12/s (n=100000)
query_param_append: 14 wallclock secs (14.27 usr +  0.01 sys = 14.28 CPU) @ 7002.80/s (n=100000)

appendの方が高速のようだ。いったんこの結果が一つの理由になるので𠮷とする。
ただ、内部的にどうなのか追いたいので後日追記します。(短いのである程度は判明してますが)