Hirofumi Wakasugi
January 22, 2016
99

# Rubyの拡張をCrystalで書いてみる

Tokyo Crystal Meetup #3 (2016-01-22)

January 22, 2016

## Transcript

2. ### /BUJWF&YUFOTJPO Fetching: nokogiri-1.6.7.1.gem (100%) Building native extensions. This could take

a while... w ಛʹ࣮ߦ଎౓͕ॏཁͳॲཧΛ\$Ͱॻ͘͜ͱ͕Ͱ͖Δ w طଘͷ\$ϥΠϒϥϦΛར༻͢Δ͜ͱ͕Ͱ͖Δ 3VCZ͸\$ݴޠͰ֦ுϥΠϒϥϦΛॻ͘͜ͱ͕Ͱ͖Δ
3. ### \$SZTUBM\$-JCSBSZ#JOEJOHT lib LibC fun pow(x: Float64, y: Float64) : Float64

fun sqrt(val: Float64) : Float64 end puts(LibC.pow(10, 10)) puts(LibC.sqrt(4)) end \$SZTUBMͰ\$ͷόΠϯσΟϯάΛॻ͘ͷ͸ͱͯ΋؆୯

5. ### def fibonacci(n) return n if n <= 1 fibonacci(n -

1) + fibonacci(n - 2) end ·ͣɺ͜ͷ୯७ͳϑΟϘφον਺ྻͷؔ਺Λ 3VCZ֦ுϥΠϒϥϦͱͯ͠\$SZTUBMͰॻ͖·͢ &YBNQMF
6. ### lib LibRuby type VALUE = Void* \$rb_cObject : VALUE fun

rb_define_global_function(name : UInt8*, func : VALUE, VALUE -> VALUE, argc : Int32) fun rb_num2int(value : VALUE) : Int32 fun rb_int2inum(value : Int32) : VALUE end def fibonacci_cr(self : LibRuby::VALUE, value : LibRuby::VALUE) int_value = LibRuby.rb_num2int(value) LibRuby.rb_int2inum(fibonacci_cr2(int_value)) end def fibonacci_cr2(n) return n if n <= 1 fibonacci_cr2(n - 1) + fibonacci_cr2(n - 2) end fun init = Init_extension_with_crystal GC.init LibCrystalMain.__crystal_main(0, Pointer(Pointer(UInt8)).null) LibRuby.rb_define_global_function("fibonacci_cr", ->fibonacci_cr, 1); end &YBNQMFpCPCBDDJ@DS
7. ### user system total real fibonacci (ruby) 16.760000 0.040000 16.800000 (

16.963310) fibonacci (crystal) 0.830000 0.010000 0.840000 ( 0.827128) ͏Μɺ଎͍ &YBNQMF
8. ### class Takeuchi def self.tarai(x, y, z) if y < x

tarai( tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y) ) else y end end end ͨΒ͍ճؔ͠਺΋ॻ͍ͯΈ·͢ &YBNQMF
9. ### lib LibRuby type VALUE = Void* \$rb_cObject : VALUE fun

rb_define_class(name : UInt8*, super : VALUE) : VALUE fun rb_define_module_function(klass : VALUE, name : UInt8*, func : VALUE, VALUE, VALUE, VALUE -> VALUE, argc : Int32) fun rb_num2int(value : VALUE) : Int32 fun rb_int2inum(value : Int32) : VALUE end def tarai(self : LibRuby::VALUE, x : LibRuby::VALUE, y : LibRuby::VALUE, z : LibRuby::VALUE) int_x = LibRuby.rb_num2int(x) int_y = LibRuby.rb_num2int(y) int_z = LibRuby.rb_num2int(z) LibRuby.rb_int2inum(tarai2(int_x, int_y, int_z)) end def tarai2(x, y, z) if y < x tarai2( tarai2(x - 1, y, z), tarai2(y - 1, z, x), tarai2(z - 1, x, y) ) else y end end fun init = Init_extension_with_crystal GC.init LibCrystalMain.__crystal_main(0, Pointer(Pointer(UInt8)).null) rb_class_takeuchi = LibRuby.rb_define_class("TakeuchiCr", LibRuby.rb_cObject) LibRuby.rb_define_module_function(rb_class_takeuchi, "tarai", ->tarai, 3); end &YBNQMF5BLFVDIJ\$SUBSBJ
10. ### user system total real tarai (ruby) 19.810000 0.050000 19.860000 (

20.248620) tarai (crystal) 0.970000 0.000000 0.970000 ( 0.998764) ͏Μɺ଎͍ &YBNQMF

12. ### 5TVSBNJ person = LibRuby.rb_define_class("Person", LibRuby.rb_cObject) LibRuby.rb_define_method(person, "Hello", ->hello, 1); w

\$SZTUBMͷදݱྗΛ׆༻͢Δ͜ͱ͕೉͍͠ w ن໛͕େ͖͘ͳͬͯ͘Δͱ͔ͳΓݟ௨͕͠ѱ͘ͳΔ ݁ہɺී௨ʹ࢖͏ͱ\$"1*ͷόΠϯσΟϯάͰ͔͠ͳ͍
13. ### 5TVSBNJ #define RB_FIX2LONG(x) ((long)RSHIFT((SIGNED_VALUE)(x),1)) #define StringValuePtr(v) rb_string_value_ptr(&(v)) w \$͔ΒѻΘͳ͍৔߹γϯϘϧΛએݴ͢Δͷ͕େม w

ຖճʮSVCZIʯͱ͔Λ͕Μ͹ͬͯಡΉ͜ͱʹͳΔ 3VCZ\$"1*Ͱ͸ϚΫϩ͕ଟ༻͞ΕΔ
14. ### 5TVSBNJ fun rb_define_method(klass : VALUE, name : UInt8*, func :

VALUE, VALUE -> VALUE, argc : Int32) w ؔ਺ͷܕΛࢦఆ͢Δඞཁ͕͋Δ w ͜ΕҎ֎ͷܕͷؔ਺Λ౉͢ͱίϯύΠϧΤϥʔ 3VCZ\$"1*ؔ਺ͷҾ਺͕ؔ਺ϙΠϯλͷͱ͖ʜ

16. ### 1SPPGPG\$PODFQU 1P\$ ruby_extension "test_ruby", class Foo def foo(a) "From Crystal!!

#{a}" end end SVCZ@FYUFOTJPOϚΫϩͰίʔυ จࣈྻ Λॲཧ ϚΫϩʹ౉͞Εͨίʔυ͸1BSTFSͰύʔε͞ΕΔ
17. ### 1SPPGPG\$PODFQU 1P\$ class MyVisitor < Visitor … def visit(node :

ClassDef) @str << %(_class = Ruby::Class.new "#{node.name}"\n) end def visit(node : Def) @str << %(_class.def "#{node.name}", #{node.args.size}, ) @str << %[->(self : LibRuby::VALUE, ] node.args.each do |arg| @str << %(_#{arg.name} : LibRuby::VALUE, ) … end … end "45ϊʔυ͸7JTJUPSΛܧঝͨ͠ΫϥεͰॲཧ͞ΕΔ ؔ਺ϙΠϯλ͸ܕΛ7PJE Ͱఆ͓͍ٛͯͯ͠ɺ͜͜Ͱ۩ମతͳܕͱͯ͠ઃఆ͞ΕΔ

19. ### .BUPNF w 3VCZͷ֦ுΛ\$SZTUBMͰॻ͚Δɺ͕ී௨ʹॻ͘ͱͭΒ͍ w Ͱ΋ɺ\$SZTUBMͰ֦ுΛॻ͘ར఺͸େ͖͍ ‣ ΍ͬͺΓ଎͍ ‣ 3VCZͷγϯλοΫεͱඇৗʹ͍ۙ w

ެ͕ࣜ3VCZͷ֦ுʹରͯ͠ੵۃత