satoのメモ用サイト
2016年4月17日日曜日
2016年4月7日木曜日
.screenrc
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でデバッグ
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の謎な概念を丁寧に解説してくれている。書籍版の購入がオススメ。
ペンシルバニア州立大学の講義、Haskell初心者に大人気で、ペンシルバニア大学の学生以外も勝手にやっている。
講義資料と宿題があり、といていくとHaskell的なプログラムを書けるようになる。
再帰を頻繁に使い、手続き型言語しかやっていない人は確実に躓く。アメリカの大学だけあってさすがに難度が高い。
欠点は講義資料という性質上、宿題の答えが用意されていないことだが、githubで検索すると自分なりの回答を載せている人がたくさんいるため参考にできる。
Fpcompleteという会社の解説記事。関数の呼び出し方のような基本的な内容から、並列処理の実装方法といった応用的なのまで 揃っている。CIS 194で詰んだら、見てみよう。
2015年10月23日金曜日
Ruby Net::HTTPの使い方と(直接)使うべきでない時
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