è¦ã¯ä»¥ä¸ã®è¨äºã®ç¹°ãè¿ããªã®ã ãã
Kaigi on Rails _2022_ new ã¨ããã¤ãã³ãã® LT ã§ãã¡ã½ããå®ç¾©ãæ¢ããã¨ãã話ããã£ãã
Rails ã®ã½ã¼ã¹ãã·ã¥ãã¨çºãã«è¡ãã¨ãããé常ã«å°ãè¯ãçºè¡¨ã§ããã
Object ã®ãã¨ã¯ Object ã«èãã㯠Ruby ã®é常ã«é¢ç½ãã¨ãããªã®ã§ãMethod ãåãåºã㦠source_location
ãå°ããã®ã¯ä¸åº¦ä½é¨ãã¦æåãã¦æ¬²ãããã ãã©ãå®åã ã¨ã¿ã¤ãæ°ã®å°ãªãããæ¹ãç¥ã£ã¦ããã¨æ´ã«ä¾¿å©ã«ä½¿ããã®ã§ãç´¹ä»ã
irb ã® show_source ãæ¦å¨ã«å ãã¦ãããã #kaigionrails
— Takafumi ONAKA (@onk) October 9, 2022
Pry ã® $
irb ãããè²ã ã§ãã¦ä¾¿å©ãª REPLãã¨ããã®ã§ãã使ããã¦ãã gem ã ã¨æãããã®å¾ irb ã追ãã¤ãã¦è¿½ãè¶ãã¦ãã£ãã®ã§å¤å使ãã©ããã¯æ¸ã£ã¦ãã¦ããããæ¢åã®ã³ã¼ããã¼ã¹ã«ã¯å ¥ã£ã¦ãããã¨ãå¤ãã ããã
pry ã«ã¯ show-source
(alias ã® $
ããã使ã) ã¨ããæ©è½ããã£ã¦ãã¡ã½ããã®å®ç¾©ã«é常ã«ç°¡åã«ã¢ã¯ã»ã¹ã§ããã
https://github.com/pry/pry/blob/v0.14.1/lib/pry/commands/show_source.rb
使ãæ¹ï¼
$ bundle exec pry [1] pry(main)> require "set" => true [2] pry(main)> $ Set#merge From: /opt/rubies/3.1.2/lib/ruby/3.1.0/set.rb:603: Owner: Set Visibility: public Signature: merge(enum) Number of lines: 9 def merge(enum) if enum.instance_of?(self.class) @hash.update(enum.instance_variable_get(:@hash)) else do_with_enum(enum) { |o| add(o) } end self end
ã¡ã½ãã表示æã« Syntax Highlight ãå ¥ã£ã¦ãã¦ãé常ã«è¦ãããã
pry ã«ã¯ pry-doc ã¨ãã plugin ããã£ã¦ãããã使ã㨠C è¨èªã§å®è£ ããã¦ããã¡ã½ãããèªã¿ã«è¡ããã®ã好ãã§ãã
[1] pry(main)> $ puts From: io.c (C Method): Owner: Kernel Visibility: private Signature: puts(*arg1) Number of lines: 9 static VALUE rb_f_puts(int argc, VALUE *argv, VALUE recv) { VALUE r_stdout = rb_ractor_stdout(); if (recv == r_stdout) { return rb_io_puts(argc, argv, recv); } return forward(r_stdout, rb_intern("puts"), argc, argv); }
æè¿ ãã¡ãã®ã¨ã³ã㪠ã§ãç´¹ä»ããã¦ããã(ãããªã¬)
IRB ã® show_source
irb ã«ã show_source
ã³ãã³ãããããã¨ããã pry ã®åæ©è½ã欲ãã㦠id:k0kubun ãããå
¥ããã
https://github.com/ruby/irb/blob/v1.4.2/lib/irb/cmd/show_source.rb
irb ã® show_source
ã IRB::Color
ã¨ãã Syntax Highlight ã®ä»çµã¿ã使ããã¦ãã¦ãèªã¿ããããªã£ã¦ããã
ãªããirb ã®å¶éã¨ãã¦ãRubyã¨ãã¦validãªå
¥åããã§ããªããã¨ããã®ããããpry ã¨åãæ¸ãå¿å°ã§ã¯ãªã ($
ã® alias ã¯ç¡ãããå¼æ°ãæååã¨ãã¦æ¸¡ããªããã°ãããªã) ããããã§ã irb ã« show_source
ãããã®ã¯æé«ã§ããã¨ããããpry ã® show-source
ãå¤ç¨ãã¾ãã£ã¦ããã®ã§ããããç¡ãã¨å㯠pry ãåæ¥ã§ããªãã£ãã
ããã¦ãã¨ã³ããªã«ãããéã .irbrc
ã«ç´°å·¥ããã㨠$
ãåç¾ã§ããã
# .irbrc IRB::Context.prepend(Module.new{ def evaluate(line, *, **) case line when /\A\$ / line.replace("show_source #{line.sub(/\A\$ /, '').strip.dump}\n") end super end })
軽ã説æããã¨
IRB::Context.prepend
- å
¥åã eval ããé¨åã«ä»å
¥ãããã®ã§
IRB::Context#evaluate
ãprepend
ã§ä¸æ¸ããã
- å
¥åã eval ããé¨åã«ä»å
¥ãããã®ã§
Module.new{}
prepend
&&super
ããããã«ç¡åã¢ã¸ã¥ã¼ã«ãä½ã£ã¦ãã
when /\A\$ /
- å
¥åã
$
ã§å§ã¾ã£ã¦ããã
- å
¥åã
line.replace("show_source #{line.sub(/\A\$ /, '').strip.dump}\n")
show_source "..."
ã«æ¸ãæãã¦
super
evaluate
ãå®è¡ãã
ã¯ãã
ããã§ã¿ã¤ãæ°å°ãªãå®è£
ãèªã¿ã«è¡ããããã«ãªã£ããshow_source
ãæå¾
ã¨éã£ããã¨ãã人ããããªãæºè¶³ããããããªãã§ããããã
$ irb irb(main):001:0> $ Set#merge From: /opt/rubies/3.1.2/lib/ruby/3.1.0/set.rb:605 def merge(enum) if enum.instance_of?(self.class) @hash.update(enum.instance_variable_get(:@hash)) else do_with_enum(enum) { |o| add(o) } end self end => nil
irb ä¸ã®å ¥åãå å·¥ã㦠eval ããæ段ãããã§åãã£ãã®ã§ãèªåã®é¢ç½æ©è½ãè²ã¦ã¦ããã¨è¯ãã¨æãã
ãããããä¸å£°
pry ã® show-source
㯠--super
ãã¡ãã£ã¯ãã£ä¾¿å©ãªã®ã§ã欲ããã
ã©ããªæ©è½ãã¨ããã¨ãshow-source ã§ã¡ã½ãããèªãã§ããã¨ãã« super
ãåºã¦ããã --super
ãä»ããã¨è¦ªã¯ã©ã¹ã®ã¡ã½ããã表示ã§ããã¤ãã§ãã
ãããã C < B < A ã¨ããã¯ã©ã¹ãããã¨ãã¦ã
class A def foo puts "A" end end class B < A def foo puts "B" super end end class C < B def foo puts "C" super end end
--super
ãä»ãã¦å¼ã¶ã¨ãããªãã
[1] pry(main)> $ C.new.foo From: (pry):13: Owner: C Visibility: public Signature: foo() Number of lines: 4 def foo puts "C" super end
[2] pry(main)> $ C.new.foo --super From: (pry):7: Owner: B Visibility: public Signature: foo() Number of lines: 4 def foo puts "B" super end
è¤æ°å --super
ã渡ã㨠super_level ãä¸ããã
[3] pry(main)> $ C.new.foo --super --super From: (pry):2: Owner: A Visibility: public Signature: foo() Number of lines: 3 def foo puts "A" end
ã¨ããã®ã欲ãããã ãã©ãå¼æ°ã«æ¸¡ãããªãã¸ã§ã¯ãã® ancestors ã --super
ã®æ°ã ãé¡ãã°ã§ãããã§ã¯ãããªã .irbrc
ã§ãã£ã¦ã¿ããã¼ã