Slide 1

Slide 1 text

3VCZͷ֦ுΛ $SZTUBMͰॻ͍ͯΈΔ Writing Ruby extension with Crystal Hirofumi Wakasugi (@5t111111)

Slide 2

Slide 2 text

/BUJWF&YUFOTJPO Fetching: nokogiri-1.6.7.1.gem (100%) Building native extensions. This could take a while... w ಛʹ࣮ߦ଎౓͕ॏཁͳॲཧΛ$Ͱॻ͘͜ͱ͕Ͱ͖Δ w طଘͷ$ϥΠϒϥϦΛར༻͢Δ͜ͱ͕Ͱ͖Δ 3VCZ͸$ݴޠͰ֦ுϥΠϒϥϦΛॻ͘͜ͱ͕Ͱ͖Δ

Slide 3

Slide 3 text

$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Ͱ$ͷόΠϯσΟϯάΛॻ͘ͷ͸ͱͯ΋؆୯

Slide 4

Slide 4 text

͏ΜɺͦΕͳΒ $SZTUBMͰ3VCZͷ֦ுॻ͚ͦ͏ʂ

Slide 5

Slide 5 text

def fibonacci(n) return n if n <= 1 fibonacci(n - 1) + fibonacci(n - 2) end ·ͣɺ͜ͷ୯७ͳϑΟϘφον਺ྻͷؔ਺Λ 3VCZ֦ுϥΠϒϥϦͱͯ͠$SZTUBMͰॻ͖·͢ &YBNQMF

Slide 6

Slide 6 text

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 &YBNQMFpCPCBDDJ@DS

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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 &YBNQMF5BLFVDIJ$SUBSBJ

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

͋͞ɺͭΒ͍ͷ͸͔͜͜Β

Slide 12

Slide 12 text

5TVSBNJ person = LibRuby.rb_define_class("Person", LibRuby.rb_cObject) LibRuby.rb_define_method(person, "Hello", ->hello, 1); w $SZTUBMͷදݱྗΛ׆༻͢Δ͜ͱ͕೉͍͠ w ن໛͕େ͖͘ͳͬͯ͘Δͱ͔ͳΓݟ௨͕͠ѱ͘ͳΔ ݁ہɺී௨ʹ࢖͏ͱ$"1*ͷόΠϯσΟϯάͰ͔͠ͳ͍

Slide 13

Slide 13 text

5TVSBNJ #define RB_FIX2LONG(x) ((long)RSHIFT((SIGNED_VALUE)(x),1)) #define StringValuePtr(v) rb_string_value_ptr(&(v)) w $͔ΒѻΘͳ͍৔߹γϯϘϧΛએݴ͢Δͷ͕େม w ຖճʮSVCZIʯͱ͔Λ͕Μ͹ͬͯಡΉ͜ͱʹͳΔ 3VCZ$"1*Ͱ͸ϚΫϩ͕ଟ༻͞ΕΔ

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

DSZTUBM@SVCZ 8SJUF3VCZFYUFOTJPOTJO$SZTUBM IUUQTHJUIVCDPNNBOBTUFDIDSZTUBM@SVCZ w ެࣜʹΑΔʮ1SPPGPG$PODFQUʯ w ҙࣝߴ͍ w ࠷৽ͷ$SZTUBMͰ͸ಈ͔͢ͷʹͪΐͬͱमਖ਼͕ཁΔ

Slide 16

Slide 16 text

1SPPGPG$PODFQU 1P$ ruby_extension "test_ruby", class Foo def foo(a) "From Crystal!! #{a}" end end SVCZ@FYUFOTJPOϚΫϩͰίʔυ จࣈྻ Λॲཧ ϚΫϩʹ౉͞Εͨίʔυ͸1BSTFSͰύʔε͞ΕΔ

Slide 17

Slide 17 text

1SPPGPG$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 Ͱఆ͓͍ٛͯͯ͠ɺ͜͜Ͱ۩ମతͳܕͱͯ͠ઃఆ͞ΕΔ

Slide 18

Slide 18 text

·ͱ΋ʹಈ͔ͳ͍͚Ͳҙࣝߴ͍1P$

Slide 19

Slide 19 text

.BUPNF w 3VCZͷ֦ுΛ$SZTUBMͰॻ͚Δɺ͕ී௨ʹॻ͘ͱͭΒ͍ w Ͱ΋ɺ$SZTUBMͰ֦ுΛॻ͘ར఺͸େ͖͍ ‣ ΍ͬͺΓ଎͍ ‣ 3VCZͷγϯλοΫεͱඇৗʹ͍ۙ w ެ͕ࣜ3VCZͷ֦ுʹରͯ͠ੵۃత

Slide 20

Slide 20 text

ޚ੩ௌ ༗೉͏ޚ࠲͍·ͨ͠ ຊεϥΠυதͷαϯϓϧίʔυ ͓Αͼͦͷग़ྗ಺༰͸ ͢΂ͯ$SZTUBMͰ֬ೝ͍ͯ͠·͢ LIVE FOREVER