2016年4月7日木曜日

.screenrc

Screenの設定ファイルはこんな感じで
term screen-256color
escape ^Oo
termcapinfo xterm* ti@:te@

hardstatus alwayslastline
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%t%n*%f%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B} %m-%d %{W}%c %{g}]'
チートシート: http://www.pixelbeat.org/lkdb/screen.html

2016年2月20日土曜日

pythonのスクリプトファイルとの相対パス

import os

this_dir = os.path.dirname(os.path.realpath(__file__))
filename = os.path.join(this_dir, 'lib')
print filename

2016年2月19日金曜日

python によるPID のロック

import time
import os
import sys

pid = str(os.getpid())
pidfile = "/tmp/scripy.pid"

if os.path.isfile(pidfile):
    print "exit"
    sys.exit(0)
file(pidfile, 'w').write(pid)
try:
    f = open('workfile', 'a')
    f.write("1")
    f.close
    time.sleep(10)

finally:
    os.unlink(pidfile)

2015年12月31日木曜日

MRIをでバックビルドしてgdbでデバッグ

Untitled Document.md

MRIのビルド

./configure時の–enable-debug-envオプションは、コンパイラによる最適化を抑止してgdbでソースをおえるようにしてくれているはず。 システムのrubyと競合しないように–prefixでインストール先を指定する。

./configure --enable-debug-env --prefix /home/sato/ruby/ CFLAGS="-g3 -O0"
make
make install

環境変数を設定

さっきインストールしたrubyの実行ファイルが呼び出されるように環境変数を設定してやる。

RUBYPATH=$HOME/ruby/bin
export RUBYPATH
export PATH=$RUBYPATH:$PATH
export RUBYLIB=$RUBYPATH/lib/ruby

gdb用のヘルパーをホームディレクトリに入れておく

rubyの内部のデータは殆どがVALUEポインタで表現され、後でキャストしてから使用される。 この時、キャスト後が何のデータであるかがわからなければ、gdbのprintで中を覗くことができない。 このため、rubyのソースにバンドルされているgdb用のヘルパーを使う。

以下からダウンロード
https://github.com/ruby/ruby/blob/trunk/.gdbinit

cp .gdbinit ~/

定義されたヘルパーの一覧はhelp user-definedで見ることができる。

(gdb) help user-defined
User-defined commands.
The commands in this class are those defined by the user.
Use the "define" command to define a command.

List of commands:


******略******

rb_p -- User-defined
rb_ps -- Dump all threads and their callstacks
rb_ps_thread -- User-defined
rb_ps_vm -- Dump all threads in a (rb_vm_t*) and their callstacks
rbi -- User-defined
rp --   Print a Ruby's VALUE
rp_class --   Print the content of a Class/Module
rp_id --   Print an ID
rp_imemo --   Print the content of a memo
rp_string --   Print the content of a String
ruby_gdb_init -- User-defined
sdr -- User-defined

重要なのはrpで、これでVALUEの中身を知ることができる。

irbを起動しgdbをアタッチ

irb

まず、起動したirbのプロセスIDを調べる。

$ ps x|grep irb
1742 pts/1    Sl+    0:00 irb

別のターミナルから起動したirbにアタッチする。

gdb /home/sato/ruby/bin/irb -p 1742

ブレークポイントを設定してみる。

  (gdb) b proc_curry
  Breakpoint 3 at 0x7f60aa2bff64: file proc.c, line 2755.
  (gdb) c
  Continuing

proc_curryはProc#curryのC側での実装。 以下の関数がそれにあたる。

  rb_define_method(rb_cMethod, "curry", rb_method_curry, -1);

  static VALUE
  proc_curry(int argc, const VALUE *argv, VALUE self)
  {
      int sarity, max_arity, min_arity = rb_proc_min_max_arity(self, &max_arity);
      VALUE arity;

      rb_scan_args(argc, argv, "01", &arity);
      if (NIL_P(arity)) {
    arity = INT2FIX(min_arity);
      }
      else {
    sarity = FIX2INT(arity);
    if (rb_proc_lambda_p(self)) {
        rb_check_arity(sarity, min_arity, max_arity);
    }
      }

      return make_curry_proc(self, rb_ary_new(), arity);
  }

この状態で、irb側から以下のようにProc#curryを呼び出す

  Proc.new {|x,y|x+y}.curry

gdbがbreakする。

  Breakpoint 1, proc_curry (argc=0, argv=0x7f48ea86d258, self=139951178000880) at proc.c:2755
  warning: Source file is more recent than executable.
  2755        int sarity, max_arity, min_arity = rb_proc_min_max_arity(self, &max_arity);

コードの中の現在位置を確認

  (gdb) l
  2750      *     p b.curry[]                  #=> :foo
  2751      */
  2752    static VALUE
  2753    proc_curry(int argc, const VALUE *argv, VALUE self)
  2754    {
  2755        int sarity, max_arity, min_arity = rb_proc_min_max_arity(self, &max_arity);
  2756        VALUE arity;
  2757
  2758        rb_scan_args(argc, argv, "01", &arity);
  2759        if (NIL_P(arity)) {

selfのVALUEポインタを見てみる。

  (gdb) rp self
  T_DATA(proc): $4 = (struct RTypedData *) 0x7f48ec4029f0
  (gdb) print *(struct RTypedData *) self
  $5 = {basic = {flags = 12, klass = 139951178175800}, type = 0x7f48eae51ca0 <proc_data_type>,
  typed_flag = 1, data = 0x7f48ec85bd80}
  (gdb) print (*(struct RTypedData *) self)->basic
  $6 = {flags = 12, klass = 139951178175800}
  (gdb) print (*(struct RTypedData *) self)->basic->klass
  $7 = 139951178175800

2015年12月20日日曜日

Haskell入門者のための素晴らしいサイト3つ

最近、Haskellを勉強しています。型クラス、型コンストラクタ、Functor、Applicative、Monoid、Monad、カリー化などなど、他のプログラミングにない謎な概念のおかげで かなりとっつきにくいです。しかし、とてもおもしろい。純粋な関数型言語で関数や型に対する厳密な制約を を持っているにもかかわらず、様々な工夫で生産性を下げないようにしています。(JAVAみたいにならない)

そんなHaskellの入門中に、これは素晴らしいと思ったHaskell入門用のサイトが以下の3つ。

Learn You a Haskell for Great Good!

書籍だが、webで無料公開している。 日本語版の本が「すごいHaskellたのしく学ぼう!」のタイトルで出版されている。 入門者が最初にみるべきだと思う。Haskellの謎な概念を丁寧に解説してくれている。書籍版の購入がオススメ。

CIS 194

ペンシルバニア州立大学の講義、Haskell初心者に大人気で、ペンシルバニア大学の学生以外も勝手にやっている。 講義資料と宿題があり、といていくとHaskell的なプログラムを書けるようになる。
再帰を頻繁に使い、手続き型言語しかやっていない人は確実に躓く。アメリカの大学だけあってさすがに難度が高い。 欠点は講義資料という性質上、宿題の答えが用意されていないことだが、githubで検索すると自分なりの回答を載せている人がたくさんいるため参考にできる。

School of Haskell

Fpcompleteという会社の解説記事。関数の呼び出し方のような基本的な内容から、並列処理の実装方法といった応用的なのまで 揃っている。CIS 194で詰んだら、見てみよう。

2015年10月23日金曜日

Ruby Net::HTTPの使い方と(直接)使うべきでない時

Untitled Document.md

rubyで単純なHTTP Getをするのであれば、openuriが圧倒的に便利ファイルと同じように、http getリクエストを扱えてしまう。
しかし、比較的複雑なリクエスト(例:POST、ヘッダに何か入れる)の場合、net/httpを使う。

最も単純なGET

Net::HTTPでのgetは以下のようになる。 この程度ならopenuriを使った方が良い。

require "net/http"

# レスポンスをブロックの外で使いたい時には事前に定義しておこう
# ブロックがクロージャであることを忘れずに
response=nil

uri = URI.parse("http://example.net/")
Net::HTTP.start(uri.host, uri.port) do |http|
  response = http.get("/index.html")
  puts response.code # ステータスコード
  puts response.message # メッセージ
  puts response.body # レスポンスボディ
end

puts response.message # => OK

以下のようにインスタンスを作成してからコネクションを開く事もできる。
しかしこの場合には、最後にクローズしないとだめ。忘れるとシツレイ。
startにブロックを渡せば、ファイルオープンと同じように最後にクローズを勝手にやってくれるので安心。

http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new("/index.html")
http.close

HTTPSへのGET

以下のようにstartの引数に:use_ssl=>trueを渡してやる。

require "net/http"

uri = URI.parse("https://example.net/")
Net::HTTP.start(uri.host, uri.port,:use_ssl=>true) do |http|
  response = http.get("/index.html")
  puts response.body
end

POSTの場合

require "net/http"

uri = URI.parse("http://example.net/")
Net::HTTP.start(uri.host, uri.port) do |http|
  response = http.post("/search.cgi",'query=foo',header=nil)
  puts response.code
  puts response.message
  puts response.body
end

素晴らしいNet::HTTP解説のリンク

チートシート
http://www.rubyinside.com/nethttp-cheat-sheet-2940.html

RestでJSONリクエストを投げる例。
https://www.socialtext.net/open/very_simple_rest_in_ruby_part_3_post_to_create_a_new_workspace
http://altarf.net/computer/ruby/2890

restを作る時に便利なgem
https://github.com/rest-client/rest-client

以下に該当する場合にはNet::HTTPを使うべきでない。

単純なGETしかしない

→openuriを使う
http://ruby-doc.org/stdlib-2.1.0/libdoc/open-uri/rdoc/OpenURI.html

クローラーを作りたい

→anemoneを使う
https://github.com/chriskite/anemone

Amazonの商品検索、操作APIを使いたい

→asinを使う
https://github.com/phoet/asin

AWSのRESTを使いたい

→aws-sdk-rubyを使う
https://github.com/aws/aws-sdk-ruby

なんかRESTを使いたい。

→rest-clientを使う
https://github.com/rest-client/rest-client