続 iTerm2(MacOSX)でpromptが激しく文字化けしたとき
以前、こんな記事を書きました。
そう、MacOSXでiterm2使っていて、コマンドプロンプトが文字化けして仕方ない。
そんなときの対処方法です。
最近、またこれが発生して、同じ方法で対応したんですが、、、
全然直らない!!!!
「むきーーー!!!」ってなってぐぐりました。
そしたら、terminalで、resetコマンド叩けば?
ということで、、、
$ reset
(当然文字化けしてるので、resetって出ないけど)
直った!!!すぐ直った!こっちのほうが強力!
ちなみに、man resetしてみたら、resetコマンド自体は、tputコマンドのsubcommandで、
$ tput reset
と同義らしい。
tputは、terminfo DBをみて、terminalを初期化したりresetしたりするそうです。
ちなみに、man terminfo したところ、terminfo DBは、CSVで、/usr/share/terminfo配下にあるみたい。
でもここにあるファイルは、tic(terminfo compiler) で、コンパイルされたファイルなので、直接はみれまてん。
$ infocmp xterm # Reconstructed via infocmp from file: /usr/share/terminfo/78/xterm xterm|xterm terminal emulator (X Window System), am, bce, km, mc5i, mir, msgr, npc, xenl, colors#8, cols#80, it#8, lines#24, pairs#64, acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, civis=\E[?25l, clear=\E[H\E[2J, cnorm=\E[?12l\E[?25h, cr=^M, csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H, cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C, cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A, cvvis=\E[?12;25h, dch=\E[%p1%dP, dch1=\E[P, dl=\E[%p1%dM, dl1=\E[M, ech=\E[%p1%dX, ed=\E[J, el=\E[K, el1=\E[1K, flash=\E[?5h$<100/>\E[?5l, home=\E[H, hpa=\E[%i%p1%dG, ht=^I, hts=\EH, ich=\E[%p1%d@, il=\E[%p1%dL, il1=\E[L, ind=^J, indn=\E[%p1%dS, invis=\E[8m, is2=\E[!p\E[?3;4l\E[4l\E>, kDC=\E[3;2~, kEND=\E[1;2F, kHOM=\E[1;2H, kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~, kPRV=\E[5;2~, kRIT=\E[1;2C, kb2=\EOE, kbs=^H, kcbt=\E[Z, kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, kdch1=\E[3~, kend=\EOF, kent=\EOM, kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[1;2P, kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S, kf17=\E[15;2~, kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~, kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R, kf28=\E[1;5S, kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~, kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~, kf36=\E[24;5~, kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R, kf4=\EOS, kf40=\E[1;6S, kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~, kf44=\E[19;6~, kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~, kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q, kf51=\E[1;3R, kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~, kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~, kf58=\E[21;3~, kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~, kf61=\E[1;4P, kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~, kind=\E[1;2B, kmous=\E[M, knp=\E[6~, kpp=\E[5~, kri=\E[1;2A, mc0=\E[i, mc4=\E[4i, mc5=\E[5i, meml=\El, memu=\Em, op=\E[39;49m, rc=\E8, rev=\E[7m, ri=\EM, rin=\E[%p1%dT, rmacs=\E(B, rmam=\E[?7l, rmcup=\E[?1049l, rmir=\E[4l, rmkx=\E[?1l\E>, rmm=\E[?1034l, rmso=\E[27m, rmul=\E[24m, rs1=\Ec, rs2=\E[!p\E[?3;4l\E[4l\E>, sc=\E7, setab=\E[4%p1%dm, setaf=\E[3%p1%dm, setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m, sgr0=\E(B\E[m, smacs=\E(0, smam=\E[?7h, smcup=\E[?1049h, smir=\E[4h, smkx=\E[?1h\E=, smm=\E[?1034h, smso=\E[7m, smul=\E[4m, tbc=\E[3g, u6=\E[%i%d;%dR, u7=\E[6n, u8=\E[?1;2c, u9=\E[c, vpa=\E[%i%p1%dd,
みたいに、terminal指定して、infocmp実行すると、中身がみえます。
ここに、各terminalの情報が書いてあって、tputはこれをもとに初期化/resetをしてくれる、と。
そんな感じでした。
まぁそうなると、前回書いた、resetとの違いが何かは気になるけど・・・・
ま、それはまたそのうち・・・w
New Relic、どのProductを使えばいいの!?
概要
久しぶりに、New Relicをみてみたら、PRODUCTが多すぎて、
自分が何を使えばいいのかわからない!w
Zabbixなのか、New Relicなのか、検討しようと思ったけど、
New Relicの中でもどれなんだ!?っていう。。。
こんなにあるのです。
- New Relic APM
- New Relic INSIGHTS
- New Relic MOBILE
- New Relic BROWSER
- New Relic SYNTHETICS
- New Relic SERVERS
- New Relic PLUGINS
- New Relic for iOS & Android
Software Analytics SaaS Application Monitoring Products: New Relic | New Relic
ちなみに、今回は、普通に、ApサーバとRDSの単純構成のサービスを
監視したいだけ。難しいことは一切なし。
ということで、New Relicのプロダクトをざっと並べてみました。
New Relic APM
まず、APMは、Application Performance Monitoringの略でした。すっきり。
アプリケーションのパフォーマンスを詳細に分析して、DBのボトルネックやら、
どのAPIが処理が遅いか、そもそも、NWが遅いのか、アプリの内部処理が遅いのか、
viewのDOM構築が遅いのか、レンダリングが遅いのか、などなどを見せてくれる。
すごい便利ツール。これ!これは今回みたかったやつ!
New Relic MOBILE
どうやら、MOBILEは、モバイルのネイティブアプリのツールぽい。
例えば、どの辺の地域でパフォーマンスがよくないか、とか
どのサードパーティAPIがパフォーマンス劣化につながってるか、
とか、OS毎、デバイス毎、アプリバージョン毎のパフォーマンスの
違いをみれたりするんだと。
あとキャリアによる違いとか。これは、今回ほしいのではない、なと。
New Relic BROWSER
これはほんとにフロントのブラウザ処理を徹底解析!って感じ。
AJAXの処理時間を細かく出してくれるので、それに基づいた改善をしていける。
ユーザがロードした、全asset/ajax request/ユーザインタラクションなどなど、
タイムラインにしてみせてくれるから改善しやすい。
APMでざっくりみて、DOM ProcessingとかRenderingに問題あったらこっちみる感じかな。
でも今回はここじゃないからいいや、と。
New Relic SYNTHETICS
これは、世界中からレスポンスタイム測ってくれるってやつか。
すげーな。でもこれも今回違うからいいや。
New Relic SERVERS
書いてあるとおり、サーバ監視です。
CPUとか、メモリとか、ディスク使用量とかトラフィックとか監視してくれる。
しかも、、、
New Relic Servers is 100% free, setup is easy, and you can start seeing valuable data in just minutes.
ムリョウ!!!!すごい。太っ腹。
New Relic PLUGINS
これは、単に沢山Pluginがあるよ、ってことでした。
もちろん、、、
All the data, insights, and customized plugins you need. All for FREE.
ムリョウ!!!
New Relic INSIGHTS
INSIGHTSは、データ解析ツール。
SYNTHETICS/MOBILE/BROWSER/APMから取得したデータに、
appId/appName/databaseDurationなんていう、アトリビュートをつけて、
全部溜め込んでくれます。
で、NRQLっていうDSLでリアルタイムに処理して、GUIに見せるらしいです。
何がみれるかはわからないけど、今回のとはちと違う。
というわけで、今回は、APMとSERVERの組み合わせが一番いいのかな、と。
で、ここまできて友人に聞いたところ、New Relicは、メトリクスとるのとかは
少し弱くて、カスタマイズ性もそこまで高くないので、Zabbixと併用パターンが
多い気がする、と。
はふ、そうなのか。結局あの見づらいZabbixなのか・・・
というわけで、次はmackerelもみてみることにしよう。
ざびちゃんができる子なのは知ってるけど、見づらいのよ。
rubyのオブジェクトのメソッド探索ルール
概要
最近、ActiveRecordのコードを読み始めてすぐにやめたわけです。
"super" つっても、どこの何を呼び出してるか全然わからんちんですよ。
それでまずは、表題の件(rubyでオブジェクトのメソッド探索ルール)について
調べてから立ち向かおうかと。
この辺を参考に。(本記事もこの辺を参考にオマージュしております) Rubyメソッド探索 [Ruby] オブジェクトのメソッド探索順序 - Qiita
まず、下記メソッドを沢山使いました。
# 継承ツリーを取得 <クラス>.ancestors
あと、本記事では使い忘れてしまったけど、下記メソッドも便利そうです。
# メソッドのオーナーを取得 <インスタンス>.method(:<メソッド名>).owner
本記事では、下記メソッドを使った場合のメソッド探索ルールについて調べてみます。
- extend
- include
- prepend
- 継承
まずは普通に継承してみる
# test.rb require 'rubygems' require 'bundler' Bundler.require require 'pry' class Super def method1 p "super#method1" end end class Sub < Super def method1 p "sub#method1" end end sub = Sub.new.method1
これは実行すると、当然の結果が返ってくる。
$ ruby ./test.rb "sub#method1"
次に、Subクラスの、method1を削除して実行する。(↓の状態)
# test.rb require 'rubygems' require 'bundler' Bundler.require require 'pry' class Super def method1 p "super#method1" end end class Sub < Super end sub = Sub.new.method1
えい。実行。
$ ruby ./test.rb "super#method1"
おお。これも当然。Subのancestorsをみてみると、どっちの場合も同じ。
[1] pry(main)> Sub.ancestors => [Sub, Super, Object, PP::ObjectMixin, Kernel, BasicObject]
includeをみてみる
次は、Greatモジュールを作って、Subクラスにincludeしてみた。
# test.rb require 'rubygems' require 'bundler' Bundler.require require 'pry' module Great def method1 p "great#method1" end end class Super def method1 p "super#method1" end end class Sub < Super include Great end sub = Sub.new.method1
これで実行。
$ ruby ./test.rb "great#method1"
今度は、Greatモジュールのが実行された。ancestorsは・・・
[1] pry(main)> Sub.ancestors => [Sub, Great, Super, Object, PP::ObjectMixin, Kernel, BasicObject]
おお。Superの手前に突っ込まれる、と。
prependをみてみる
次は、Fabulousモジュールを作って、Subクラスにprependしてみた。
$ ruby ./test.rb "fabulous#method1"
おおおお。更に前に突っ込まれた!ancestorsというと・・・
[1] pry(main)> Sub.ancestors => [Fabulous, Sub, Great, Super, Object, PP::ObjectMixin, Kernel, BasicObject]
おお。自分よりも前に突っ込まれている。prepend最強。
prependはruby2.0から実装された機能みたいです。
少し調べてみたところ、alias_method_chain撲滅できるぜ!なもののようです。
それが主目的で開発されたわけではないかもしれませんが。
» Ruby2.0のModule#prependは如何にしてalias_method_chainを撲滅するのか!? TECHSCORE BLOG
さてさて、ここまできたら最後だ。
extendをみてみる
extendは少し意味合いが違うメソッドな気がするけど、
似たようなことをやってるので、比べてみよう。
今度は、Miracleモジュールを作って、Subクラスにextendしてみた。
# test.rb require 'rubygems' require 'bundler' Bundler.require require 'pry' module Miracle def method1 p "miracle#method1" end end module Fabulous def method1 p "fabulous#method1" end end module Great def method1 p "great#method1" end end class Super def method1 p "super#method1" end end class Sub < Super include Great prepend Fabulous extend Miracle end Sub.new.method1 Sub.method1
実行すると、こんな感じ。
$ ruby ./test.rb "fabulous#method1" "miracle#method1"
Subクラスの特異メソッドとして動作している、と。
ancestorsは・・・
[1] pry(main)> Sub.ancestors => [Fabulous, Sub, Great, Super, Object, PP::ObjectMixin, Kernel, BasicObject]
あ、そうなのね。そうか。
instance method Object#extend (Ruby 2.0.0)
↑↑に、
" extend は、ある特定のオブジェクトだけにモジュールの機能を追加 したいときに使用します。 "
って書いてあるとおり、Subクラスのオブジェクトだけに機能が追加されてるから、
ancestorsに出てくるものではないのか。
でもメソッド探索上でいうと、特異メソッドなので、一番優先度が高い、と。
include/prependを何回も呼ぶと?
何回も呼んだときは、どれが優先度高くなるのかね。
include Great1 prepend Fabulous1 include Great2 prepend Fabulous2
こんなことをした場合。
# test.rb require 'rubygems' require 'bundler' Bundler.require require 'pry' module Fabulous1 def method1 p "fabulous1#method1" end end module Fabulous2 def method1 p "fabulous2#method1" end end module Great1 def method1 p "great1#method1" end end module Great2 def method1 p "great2#method1" end end class Super def method1 p "super#method1" end end class Sub < Super include Great1 prepend Fabulous1 include Great2 prepend Fabulous2 end Sub.new.method1
これで実行してみる。えいやー。
$ ruby ./test.rb "fabulous2#method1"
お、一番最後にprependしたFabulous2が呼ばれた。
そしてancestorsは・・・
[1] pry(main)> Sub.ancestors => [Fabulous2, Fabulous1, Sub, Great2, Great1, Super, Object, PP::ObjectMixin, Kernel, BasicObject]
おー。見事に後発優先ですな。
Fabulous2, Fabulous1
Great2, Great1
の順だもんね。なるほどなるほどー。勉強になりました。
ちなみに、少し規模が大きくなってくると、rubyは、include/prepend/extend/継承などなどの
嵐になるので、コード上書いてあるメソッドが、実際どこを呼び出してるか、
全然わかりません。なので、ちゃんとテストを書いて、ちゃんと動作するよね、
っていうのは最低限守らないと大変みたいです。
というわけで、今日はおしまい。
Facebookアプリの通信量を減らす
最近、僕そんなにFacebookみてないのに通信量だけは結構あるなー、
と思って調べてみました。
ほむほむ。動画だね、きっとね。
勝手に再生されるもんね。
そんなに見ないので自動再生じゃなくていいです。
というわけで、設定から、
アカウント設定をタップ
動画を自動再生をタップ
うぃふぃーのみ、をタップ
いぇーい。自動再生オフにしたのでこれで様子見。
かんたんぽん。
rubyのヒアドキュメント
プルリのレビューをしていたら、
method(arg1, <<-EOS.strip_heredoc, arg2) "hoge" EOS
的なコードが出現して、「これは一体なんだろう・・・」と固まりました。
グーグル先生に聞いたら、こんなサイトを紹介いただきまして、無事解決しました。
http://docs.ruby-lang.org/ja/1.9.3/doc/spec=2fliteral.html (この記事は、1.9.3の記事のようですが、僕の環境は、2.2.3です)
どうやら、rubyではヒアドキュメントはとても便利なようで、
その要素が沢山詰まったコードのようです。
- rubyのヒアドキュメントは、"<<"ではじまるけど、"<<-"で開始した場合、終端行をインデントして書ける
- rubyのヒアドキュメントは、methodをチェインして繋げられる
- rubyのヒアドキュメントは、methodの引数として渡した場合、ヒアドキュメント全体を引数として渡せる
- つまり、上のコードでいうと、第二引数には、"hoge"が渡る
- strip_heredocをコールした場合、行頭の余分な空白を削除してくれる
などなど、他にもあると思いますが、勉強になりました。
ruby code readingメモ
概要
ちょっと知りたいことがあって、ふとrubyのコードをみたのでメモ。
ちなみに初めてみるのと、そんなに舐め回すようにみたわけじゃないので、
間違ってるかもしれないです。
ただ、メモっておかないと、次みるとき忘れちゃうので・・・
なぜそんなのをみることになったか。
railsのコードの中でよく出てくる、ClassMethodsモジュールって何かね?
っていうのを調べてて、こんな記事に辿り着いたため。
Rails4 - Rails の module ClassMethods がやっている事 - Qiita
記事中に、include文の中で、append_featuresが呼ばれるんだよね、って書いてあったので、
どれどれ、どこなのかな、と思ってみてみることにしました。
詳細
なにはともあれ、rubyのソースをcloneします。
$ cd <WORKDIR> $ git clone https://github.com/ruby/ruby.git
rubyっていうディレクトリができるので、入って、lsしてみる。
$ cd ruby $ ls BSDL README.md compile.c dmydln.c eval_jump.c include man parse.y regerror.c sparc.c thread_pthread.h vm.c vm_trace.c CONTRIBUTING.md aclocal.m4 complex.c dmyenc.c ext inits.c marshal.c prelude.rb regexec.c spec thread_sync.c vm_args.c vsnprintf.c COPYING addr2line.c configure.in dmyext.c file.c insns.def math.c probes.d regint.h sprintf.c thread_win32.c vm_backtrace.c win32 COPYING.ja addr2line.h constant.h doc gc.c internal.h method.h probes_helper.h regparse.c st.c thread_win32.h vm_core.h ChangeLog array.c cont.c enc gc.h io.c miniinit.c proc.c regparse.h strftime.c time.c vm_debug.h GPL benchmark coverage encindex.h gem_prelude.rb iseq.c misc process.c regsyntax.c string.c timev.h vm_dump.c KNOWNBUGS.rb bignum.c cygwin encoding.c gems iseq.h missing random.c ruby.c struct.c tool vm_eval.c LEGAL bin debug.c enum.c golf_prelude.rb lex.c.blt nacl range.c ruby_atomic.h symbol.c transcode.c vm_exec.c Makefile.in bootstraptest defs enumerator.c goruby.c lib node.c rational.c safe.c symbol.h transcode_data.h vm_exec.h NEWS ccan dir.c error.c hash.c load.c node.h re.c sample template util.c vm_insnhelper.c README.EXT class.c dln.c eval.c ia64.s loadpath.c numeric.c regcomp.c signal.c test variable.c vm_insnhelper.h README.EXT.ja common.mk dln.h eval_error.c id_table.c localeinit.c object.c regenc.c siphash.c thread.c version.c vm_method.c README.ja.md compar.c dln_find.c eval_intern.h id_table.h main.c pack.c regenc.h siphash.h thread_pthread.c version.h vm_opts.h
おお、直下に沢山。
Cとか読むの10年ぶりくらいですけど大丈夫でしょうか。
遠い記憶を掘り起こして・・・Cはまずmain.cだ!!!
$ cat main.c /********************************************************************** main.c - $Author$ created at: Fri Aug 19 13:19:58 JST 1994 Copyright (C) 1993-2007 Yukihiro Matsumoto **********************************************************************/ #undef RUBY_EXPORT #include "ruby.h" #include "vm_debug.h" #ifdef HAVE_LOCALE_H #include <locale.h> #endif #ifdef RUBY_DEBUG_ENV #include <stdlib.h> #endif int main(int argc, char **argv) { #ifdef RUBY_DEBUG_ENV ruby_set_debug_option(getenv("RUBY_DEBUG")); #endif #ifdef HAVE_LOCALE_H setlocale(LC_CTYPE, ""); #endif ruby_sysinit(&argc, &argv); { RUBY_INIT_STACK; ruby_init(); return ruby_run_node(ruby_options(argc, argv)); } }
色々書いてあるけど、
ruby_init(); return ruby_run_node(ruby_options(argc, argv));
が次かな。ここから色々grep。
$ grep -E 'ruby_init' *.c | grep -v 'ruby_init_' debug.c: SET_WHEN("gc_stress", *ruby_initial_gc_stress_ptr, Qtrue); eval.c:ruby_init(void) gc.c:#define ruby_initial_gc_stress gc_params.gc_stress gc.c:VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress; gc.c: gc_stress_set(objspace, ruby_initial_gc_stress); loadpath.c:const char ruby_initial_load_paths[] = main.c: ruby_init(); miniinit.c:const char ruby_initial_load_paths[] = ""; ruby.c: const char *paths = ruby_initial_load_paths;
ファイル名的に怪しいのは、eval.cである。で、開いてみたところ、
起動時のキーになりそうな関数が沢山。
int ruby_setup(void) void ruby_init(void) void * ruby_options(int argc, char **argv) static void ruby_finalize_0(void) などなど
ruby_init()でなにやってるかというと・・・
書いてあるとおり、
Calls ruby_setup() and check error. Prints errors and calls exit(3) if an error occurred.
です。てコメントに書いてあるけど、EXIT_FAILUREは、defineで 1 になってる気がする。まぁいい。
/* Calls ruby_setup() and check error. * * Prints errors and calls exit(3) if an error occurred. */ void ruby_init(void) { int state = ruby_setup(); if (state) { if (RTEST(ruby_debug)) error_print(); exit(EXIT_FAILURE); } }
ruby_setup()は・・・Ruby VMとビルトインライブラリの初期化、と。
Initializes the Ruby VM and builtin libraries.
/* Initializes the Ruby VM and builtin libraries. * @retval 0 if succeeded. * @retval non-zero an error occurred. */ int ruby_setup(void) { int state; if (GET_VM()) return 0; ruby_init_stack((void *)&state); Init_BareVM(); Init_heap(); Init_vm_objects(); PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { rb_call_inits(); ruby_prog_init(); GET_VM()->running = 1; } POP_TAG(); return state; }
ここから、さっと追ってみて気になったのは、rb_call_inits()くらいかな。
inits.cに定義されている。
$ cat inits.c /********************************************************************** inits.c - $Author$ created at: Tue Dec 28 16:01:58 JST 1993 Copyright (C) 1993-2007 Yukihiro Matsumoto **********************************************************************/ #include "internal.h" #define CALL(n) {void Init_##n(void); Init_##n();} void rb_call_inits(void) { CALL(Method); CALL(RandomSeed); CALL(sym); CALL(var_tables); CALL(Object); CALL(top_self); CALL(Encoding); CALL(Comparable); CALL(Enumerable); CALL(String); CALL(Exception); CALL(eval); CALL(safe); CALL(jump); CALL(Numeric); CALL(Bignum); CALL(syserr); CALL(Array); CALL(Hash); CALL(Struct); CALL(Regexp); CALL(pack); CALL(transcode); CALL(marshal); CALL(Range); CALL(IO); CALL(Dir); CALL(Time); CALL(Random); CALL(signal); CALL(load); CALL(Proc); CALL(Binding); CALL(Math); CALL(GC); CALL(Enumerator); CALL(VM); CALL(ISeq); CALL(Thread); CALL(process); CALL(Cont); CALL(Rational); CALL(Complex); CALL(version); CALL(vm_trace); } #undef CALL
ひたすら、Init_XXXXっていうのを呼び出す関数のようで。
その中の、Init_evalってのをみてみると、
Init_eval(void) { .......... ...中略... .......... rb_define_method(rb_cModule, "include", rb_mod_include, -1); rb_define_method(rb_cModule, "prepend", rb_mod_prepend, -1); rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1); rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1); rb_define_private_method(rb_cModule, "prepend_features", rb_mod_prepend_features, 1); rb_define_private_method(rb_cModule, "refine", rb_mod_refine, 1); rb_define_private_method(rb_cModule, "using", mod_using, 1); .......... ...中略... .......... }
・・・・append_featuresがいる。includeも。
rb_define_private_methodは、名前からして、"append_features"って言ったら、rb_mod_append_featuresってことだよ。
なんだろねきっと。
そうすると、rb_mod_includeと、rb_mod_prependを調べると何かわかりそう。
$ grep rb_mod_include *.c class.c:rb_mod_included_modules(VALUE mod) class.c:rb_mod_include_p(VALUE mod, VALUE mod2) eval.c:rb_mod_include(int argc, VALUE *argv, VALUE module) eval.c: return rb_mod_include(argc, argv, th->top_wrapper); eval.c: return rb_mod_include(argc, argv, rb_cObject); eval.c: rb_define_method(rb_cModule, "include", rb_mod_include, -1); object.c: rb_define_method(rb_cModule, "included_modules", rb_mod_included_modules, 0); /* in class.c */ object.c: rb_define_method(rb_cModule, "include?", rb_mod_include_p, 1); /* in class.c */
またeval.cかな。
static VALUE rb_mod_include(int argc, VALUE *argv, VALUE module) { int i; ID id_append_features, id_included; CONST_ID(id_append_features, "append_features"); CONST_ID(id_included, "included"); for (i = 0; i < argc; i++) Check_Type(argv[i], T_MODULE); while (argc--) { rb_funcall(argv[argc], id_append_features, 1, module); rb_funcall(argv[argc], id_included, 1, module); } return module; }
というわけで、includeされたらきっとこれが呼ばれるのかな。
んで、紆余曲折あって、
rb_funcall(argv[argc], id_append_features, 1, module); rb_funcall(argv[argc], id_included, 1, module);
きっとこれで、append_featuresが呼ばれるのだろう。
これ以上みると夜になりそうなので、今日はここでおしまい。
ActiveRecordを単体で使う(rails なしで)
概要
- ActiveRecordの挙動をみたいなー
- 多少中身知りたいなー
と、思ったので、ActiveRecordだけ単体で使ってみました。
グーグル先生に聞いてみたら、やってる方を発見したので、
その通りにやってみましたメモです。
前提条件
テスト環境
- Ubuntu 14.04.1-LTS
- ruby 2.2.2p95
- AcriveRecord4.2.4
- MySQL Ver14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.3
詳細
今回は、mysqlに直接手作業でデータを突っ込んで、
それを読みだすとこまでの簡単なお仕事です。
まずは、作業用にテキトウなディレクトリを掘る
$ mkdir ar_test $ cd ar_test
Gemfileに必要なGemを書いてインストール
Gemfileはこれ。
# Gemfile source "https://rubygems.org/" gem 'mysql2', '~> 0.3.20' gem 'activerecord' gem 'pry' gem 'pry-byebug'
- DBは、mysqlにするので、mysql2
- debugというか、調査にも使いたいので、pryとpry-byebug
- mysql2だけバージョン指定してるのは、最新だとなんかがうまくいかなかったから
でbundlerでインストール。
$ bundle install
今回は、ActiveRecordは、ver4.2.4。
# Gemfile.lock GEM remote: https://rubygems.org/ specs: activemodel (4.2.4) activesupport (= 4.2.4) builder (~> 3.1) activerecord (4.2.4) activemodel (= 4.2.4) activesupport (= 4.2.4) arel (~> 6.0) activesupport (4.2.4) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) arel (6.0.3) builder (3.2.2) byebug (8.0.1) coderay (1.1.0) i18n (0.7.0) json (1.8.3) method_source (0.8.2) minitest (5.8.2) mysql2 (0.3.20) pry (0.10.3) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) pry-byebug (3.3.0) byebug (~> 8.0) pry (~> 0.10) slop (3.6.0) thread_safe (0.3.5) tzinfo (1.2.2) thread_safe (~> 0.1) PLATFORMS ruby DEPENDENCIES activerecord mysql2 (~> 0.3.20) pry pry-byebug
インストール完了。
mysql準備
ARを使いたいので、次は、mysqlを準備。
DB作成
まずはDBの作成。今回は名前は、ar_testにしよう。
$ mysql -u<username> -p<password> mysql> create database ar_test; Query OK, 1 row affected (0.00 sec) mysql> show databases; +-----------------------+ | Database | +-----------------------+ | information_schema | | ar_test | | mysql | | performance_schema | | tpcc | +-----------------------+ 5 rows in set (0.04 sec)
テーブル作成とデータ挿入
テーブル名は、test_tables。
カラムとデータは、こんなのを作っておきます。
mysql> select * from test_table; +-------+---------+ | col01 | col02 | +-------+---------+ | 1 | value01 | | 2 | value02 | +-------+---------+ 2 rows in set (0.00 sec)
コマンドは、こんなん。
mysql> create table test_tables(col01 int not null primary key, col02 varchar(64)); Query OK, 0 rows affected (2.17 sec) mysql> show tables; +-------------------+ | Tables_in_ar_test | +-------------------+ | test_tables | +-------------------+ 1 row in set (0.01 sec) mysql> insert into test_tables (col01, col02) values (1, 'value01'); Query OK, 1 row affected (0.19 sec) mysql> insert into test_tables (col01, col02) values (2, 'value02'); Query OK, 1 row affected (0.97 sec) mysql> select * from test_tables; +-------+---------+ | col01 | col02 | +-------+---------+ | 1 | value01 | | 2 | value02 | +-------+---------+ 2 rows in set (0.00 sec)
これで準備はできた。
ActiveRecordを使ってみる
早速本題。使ってみよー!
↓↓こんなtest.rbを作ってみる。
# test.rb require 'rubygems' require 'bundler' Bundler.require require 'active_record' require 'pry' database_name = :ar_test ActiveRecord::Base.establish_connection adapter: 'mysql2', database: database_name, host: 'localhost' ################################### # ここより下にテスト用のコードをかく ################################### class TestTable < ActiveRecord::Base end test_tables = TestTable.all test_tables.each do |test_table| puts test_table.col01 puts test_table.col02 end
これを実行すると・・・
$ ruby ./test.rb 1 value01 2 value02
おーー。読めた読めた。
ちゃんとDBの値が出てきておりますよー!
これで一旦は使えるようになったのかな。
おしまい。