Slide 1

Slide 1 text

਺ֶͷษڧͷͨΊʹ 3VCZͷߏจ໦ͱ༡ΜͰ͍Δ࿩ 2020.2.11. େߐށRubyձٞ08 @makicamel

Slide 2

Slide 2 text

•@makicamel / ઒ݪສق • •޷͖ͳ΋ͷ͸Ϗʔϧɹɹͱ͓ञ •ࠓ೥ޙ൒ͷ໨ඪ͸਺ֶͷษڧ ࣗݾ঺հ

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

ࠓ೔͸ 2 ݄ 11 ೔

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

•@makicamel / ઒ݪສق • •޷͖ͳ΋ͷ͸Ϗʔϧɹɹͱ͓ञ •ࠓ೥ޙ൒ͷ໨ඪ͸਺ֶͷษڧ ࣗݾ঺հ

Slide 9

Slide 9 text

•਺ֶͰͭ·ͮ͘ग़དྷࣄ͕૿͖͑ͯͨ •CRuby ࣮૷ͱ͔ Kernel Ϟδϡʔϧ (ΔΓ·) ͱ͔
 ϓϩάϥϛϯάͷجૅ (ຊ) ͱ͔ •ෳૉ਺ͱ͔ྦྷ৐ͱ͔ 2 ࣍ํఔࣜͱ͔ղͷެࣜͱ͔ •௥͍ͬͯͨίʔυɾຊ్͕੾Εͯ͠·͏ͷ΋͍ͬͨͳ͍ •ۤखҙࣝΛࠀ෰ͨ͠Β΋ͬͱָ͘͠ͳΓͦ͏ ͳͥ਺ֶʁ

Slide 10

Slide 10 text

2 ࣍ํఔࣜ ͷ܎਺ 
 (͍ͣΕ΋࣮਺ͱ͢Δ) Λ༩͑ΒΕͨΒɺ
 ൑ผࣜͷ஋Λฦؔ͢਺ Λ
 σβΠϯϨγϐ※ ʹ͕ͨͬͯ͠࡞Εɻ
 ͜͜Ͱ ͸ Ͱ͸ͳ͍ͱԾఆͯ͠Α͍ɻ ax2 + bx + c = 0 a, b, c hanbetsushiki a 0 ϓϩάϥϛϯάͷجૅ $PNQVUFS4DJFODF-JCSBSZ ୈষؔ਺ͷఆٛcઙҪ݈Ұ
 IUUQTXXXBNB[PODPKQEQ ˞σβΠϯϨγϐͱ͸͜ͷຊͰఏএ͞Ε͍ͯΔɺϓϩάϥϜ࡞੒࣌ʹ͕ͨ͠͏΂͖ࢦ਑ͷ͜ͱ ͨͱ͑͹ʁ

Slide 11

Slide 11 text

ɹɹɹɹɹɹɹɹ ͡Όͳͯ͘ɹɹɹɹ ͬͯॻ͖͍ͨ ͨͱ͑͹ʁ •൑ผࣜ •ํఔࣜ ʹରͯ͠ ͷ͜ͱ •Ruby Ͱॻ͘ͱ •௕͍ •΋͏গ͠਺ࣜͬΆ͘ॻ͖͍ͨ ax2 + bx + c b2 − 4ac b ** 2 - 4 * a * c 4 * a * c 4 a c

Slide 12

Slide 12 text

Α͠ɺ࡞Ζ͏

Slide 13

Slide 13 text

࡞ͬͨ ͯΔ NBUI@QBSTFSNBLJDBNFMNBUI@QBSTFSc(JU)VC
 IUUQTHJUIVCDPNNBLJDBNFMNBUI@QBSTFS

Slide 14

Slide 14 text

࣮૷ํ਑ •ͦ΋ͦ΋ɹɹɹɹ ͬͯॻ͘ͱͲ͏ͳΔ͔ •γϯλοΫεΤϥʔ •Ϧςϥϧɾม਺͸ۭനจࣈ۠੾ΓͰฒ΂ΒΕͳ͍※ •਺஋ͷޙʹ͓͚Δͷ͸ɹɹΈ͍ͨͳԋࢉࢠͳͲ 4 a c ˞BMJBTΩʔϫʔυ΍ه๏ͱ͍ͬͨྫ֎͕͋Γ·͢ *

Slide 15

Slide 15 text

࣮૷ํ਑ •ͦ΋ͦ΋ɹɹɹɹ ͬͯॻ͘ͱͲ͏ͳΔ͔ •γϯλοΫεΤϥʔ •Ϧςϥϧɾม਺͸ۭനจࣈ۠੾ΓͰฒ΂ΒΕͳ͍※ •਺஋ͷޙʹ͓͚Δͷ͸ɹɹΈ͍ͨͳԋࢉࢠͳͲ 4 a c ˞BMJBTΩʔϫʔυ΍ه๏ͱ͍ͬͨྫ֎͕͋Γ·͢ *

Slide 16

Slide 16 text

࣮૷ํ਑ Ruby ϓϩάϥϜͷ
 ߏจղੳΛ͢Δ

Slide 17

Slide 17 text

࣮૷ํ਑ ɹRuby Ͱͭ͘Δ Ruby ͓΋͠Ζ͔ͬͨͰ͢Αʂ @neko314_

Slide 18

Slide 18 text

Ruby Ͱͭ͘Δ Ruby •ԕ౻ (@mame) ͞Μͷஶ࡞ •ʮRuby Ͱ Ruby Λ࡞Γͳ͕ΒRuby ΛֶͿʯຊ •Ruby Ͱ Ruby ΠϯλʔϓϦλΛ࡞Δ 3VCZͰͭ͘Δ3VCZθϩ͔Βֶͼͳ͓͢ϓϩάϥϛϯάݴޠೖ໳cԕ౻ါհ
 IUUQTXXXMBNCEBOPUFDPNQSPEVDUTSVCZSVCZ ղઆ΋Θ͔Γ΍ͯ͘͢
 ֆ΋͔Θ͍ͯ͘ͱͯ΋ͨͷ͍͠

Slide 19

Slide 19 text

ࣈ۟ղੳ ߏจղੳ ࣮ߦʢܭࢉʣ Ruby Ͱͭ͘Δ Ruby

Slide 20

Slide 20 text

ࣈ۟ղੳ •ɹɹɹɹɹɹ ͱ͍͏ Ruby ϓϩάϥϜ͸ 4 * a * c def hello; "World"; end def hello ; “ World " ; end ࣈ۟ = Token (τʔΫϯ) 4 * a * c ɹɹͱ͍͏ࣈ۟ʹ෼͚ΒΕΔ •ɹɹɹɹɹɹɹɹɹɹɹɹɹɹͱ͍͏ Ruby ϓϩάϥϜ͸ ɹɹͱ͍͏ࣈ۟ʹ෼͚ΒΕΔ

Slide 21

Slide 21 text

ࣈ۟ղੳ •ࣈ۟Λղੳͯ͠ҙຯ͚ͮ͢Δ •਺஋ɺԋࢉࢠɺจࣈྻɺࣝผࢠͳͲͳͲ •ࣈ۟ղੳ = Tokenize (τʔΫφΠζ) 4 * a * c ਺஋ ԋࢉࢠ ԋࢉࢠ ࣝผࢠ ࣝผࢠ

Slide 22

Slide 22 text

ߏจղੳ •ਓ͕ؒɹɹɹ 4 * a * c 4 * a * c ΛಡΉ࣌

Slide 23

Slide 23 text

ߏจղੳ •ΠϯλʔϓϦλ͕ɹɹɹɹɹɹɹΛಡΉ࣌ 4 * a * c

Slide 24

Slide 24 text

ߏจղੳ •ΠϯλʔϓϦλ͕ɹɹɹɹɹΛಡΉ࣌ * 4 * a 4 * a

Slide 25

Slide 25 text

ߏจղੳ •ΠϯλʔϓϦλ͕ɹɹɹɹɹɹɹΛಡΉ࣌ * 4 * a * c ൓స 4 * a * c

Slide 26

Slide 26 text

ߏจղੳ •ΠϯλʔϓϦλ͕ɹɹɹɹɹɹɹΛಡΉ࣌ 4 * * * a * c ߏจ໦ 4 * a * c

Slide 27

Slide 27 text

ߏจղੳ •ΠϯλʔϓϦλ͕ɹɹɹɹɹɹɹΛಡΉ࣌ 4 * * * a * c 4 * a * c •ߏจ໦ʹม׵͢Δ͜ͱ = ߏจղੳ = Parse •ղੳͷ్தͰਖ਼͍͠ߏจ͔νΣοΫ͢Δ

Slide 28

Slide 28 text

ߏจղੳ ͜Μͳߏจ໦͕ಘΒΕͨ࣌ʹɹɹΛೖΕͨΒ͍͚ΔͷͰ͸…ʂʂ * 4 a

Slide 29

Slide 29 text

࣮૷ํ਑ •ͦ΋ͦ΋ɹɹɹɹ ͬͯॻ͘ͱͲ͏ͳΔ͔ •γϯλοΫεΤϥʔ •Ϧςϥϧɾม਺͸ۭനจࣈ۠੾ΓͰฒ΂ΒΕͳ͍※ •਺஋ͷޙʹ͓͚Δͷ͸ɹɹΈ͍ͨͳԋࢉࢠͳͲ 4 a c ˞BMJBTΩʔϫʔυ΍ه๏ͱ͍ͬͨྫ֎͕͋Γ·͢ *

Slide 30

Slide 30 text

ߏจղੳ ͜Μͳߏจ໦͕ಘΒΕͨ࣌ʹɹɹΛೖΕͨΒ͍͚ΔͷͰ͸…ʂʂ * 4 a ͜Μͳߏจ໦͸ଘࡏ͠ͳ͍

Slide 31

Slide 31 text

ߏจղੳ •ɹɹɹɹɹɹͱ͍͏τʔΫϯ͕࿈ଓͯ͠ݱΕͨΒ ɹɹɹΛૠೖͯ͠ฦ͢ 4 a ਺஋ ࣝผࢠ *

Slide 32

Slide 32 text

Ripper.lex TJOHMFUPONFUIPE3JQQFSMFYc3VCZϦϑΝϨϯεϚχϡΞϧ
 IUUQTEPDTSVCZMBOHPSHKBNFUIPE3JQQFSTMFYIUNM

Slide 33

Slide 33 text

Ripper.lex Ripper.lex('4 * a') # => [[[1, 0], :on_int, "4", END], # [[1, 1], :on_sp, " ", END], # [[1, 2], :on_op, "*", BEG], # [[1, 3], :on_sp, " ", BEG], # [[1, 4], :on_ident, "a", ARG]] Ґஔ৘ใ

Slide 34

Slide 34 text

Ripper.lex Ripper.lex('4 * a') # => [[[1, 0], :on_int, "4", END], # [[1, 1], :on_sp, " ", END], # [[1, 2], :on_op, "*", BEG], # [[1, 3], :on_sp, " ", BEG], # [[1, 4], :on_ident, "a", ARG]] ੔਺ ۭനจࣈ ԋࢉࢠ ࣝผࢠ

Slide 35

Slide 35 text

Ripper.lex Ripper.lex('4 * a') # => [[[1, 0], :on_int, "4", END], # [[1, 1], :on_sp, " ", END], # [[1, 2], :on_op, "*", BEG], # [[1, 3], :on_sp, " ", BEG], # [[1, 4], :on_ident, "a", ARG]] τʔΫϯจࣈྻ

Slide 36

Slide 36 text

Ripper.lex Ripper.lex('4 * a') # => [[[1, 0], :on_int, "4", END], # [[1, 1], :on_sp, " ", END], # [[1, 2], :on_op, "*", BEG], # [[1, 3], :on_sp, " ", BEG], # [[1, 4], :on_ident, "a", ARG]] State

Slide 37

Slide 37 text

Ripper::Lexer::State Ripper::Lexer.constants.select do |constant| constant.to_s.start_with? :EXPR.to_s end # => [ :EXPR_NONE, :EXPR_BEG, :EXPR_END, :EXPR_ENDARG, :EXPR_ENDFN, :EXPR_ARG, :EXPR_CMDARG, :EXPR_MID, :EXPR_FNAME, :EXPR_DOT, :EXPR_CLASS, :EXPR_LABEL, :EXPR_LABELED, :EXPR_FITEM, :EXPR_VALUE, :EXPR_BEG_ANY, :EXPR_ARG_ANY, :EXPR_END_ANY ] •τʔΫϯͷ State

Slide 38

Slide 38 text

class RDoc::Parser::RipperStateLex class InnerStateLex < Ripper::Filter private def on_variables(event, tok, data) if @in_fname @lex_state = EXPR_ENDFN @in_fname = false @continue = false elsif @continue case @lex_state when EXPR_DOT @lex_state = EXPR_ARG else @lex_state = EXPR_ENDFN @continue = false end else @lex_state = EXPR_CMDARG end data << Token.new(lineno, column, event, tok, @lex_state) end # ... end •ϓϩάϥϜͷͲ͜ʹ͋Δ͔ʹΑͬͯState͕มԽ͢Δ

Slide 39

Slide 39 text

ܭࢉͷ࣮ߦ def evaluate(tree, genv, lenv) case tree[0] when "lit" tree[1] when "+" evaluate(tree[1], genv, lenv) + evaluate(tree[2], genv, lenv) when "-" evaluate(tree[1], genv, lenv) - evaluate(tree[2], genv, lenv) when "*" evaluate(tree[1], genv, lenv) * evaluate(tree[2], genv, lenv) when "/" evaluate(tree[1], genv, lenv) / evaluate(tree[2], genv, lenv) when "**" evaluate(tree[1], genv, lenv)**evaluate(tree[2], genv, lenv) when "%" evaluate(tree[1], genv, lenv) % evaluate(tree[2], genv, lenv) when "<" evaluate(tree[1], genv, lenv) < evaluate(tree[2], genv, lenv) when "<=" evaluate(tree[1], genv, lenv) <= evaluate(tree[2], genv, lenv) when ">" # ... 3VCZͰͭ͘Δ3VCZθϩ͔Βֶͼͳ͓͢ϓϩάϥϛϯάݴޠೖ໳cԕ౻ါհ
 IUUQTXXXMBNCEBOPUFDPNQSPEVDUTSVCZSVCZ

Slide 40

Slide 40 text

खॱ 1. Ripper ʹ͔͚ͯߏจղੳ͕Ͱ͖Δ͔νΣοΫ 2. Ͱ͖ͳ͚Ε͹਺஋ͱม਺͕ฒΜͰ͍ΔจࣈྻΛ୳͢ 3. ਺஋ͱม਺ͷؒʹ * Λૠೖͯ͠ฦ͢ 4. 1 ʙ 3 ͷ܁Γฦ͠ 5. * ͕ૠೖ͞Εͨߏจ໦Λ࣮ߦ (ܭࢉ) ͢Δ ※ ߏจղੳ͸
 Ruby Ͱͭ͘Δ Ruby ͷิॿϥΠϒϥϦ
 minrubyΛ࢖͍·͢ NJOSVCZNBNFNJOSVCZc(JU)VC
 IUUQTHJUIVCDPNNBNFNJOSVCZ

Slide 41

Slide 41 text

खॱ 1. Ripper ʹ͔͚ͯߏจղੳ͕Ͱ͖Δ͔νΣοΫ 2. Ͱ͖ͳ͚Ε͹਺஋ͱม਺͕ฒΜͰ͍ΔจࣈྻΛ୳͢ 3. ਺஋ͱม਺ͷؒʹ * Λૠೖͯ͠ฦ͢ 4. 1 ʙ 3 ͷ܁Γฦ͠ 5. * ͕ૠೖ͞Εͨߏจ໦Λ࣮ߦ (ܭࢉ) ͢Δ NJOSVCZNBNFNJOSVCZc(JU)VC
 IUUQTHJUIVCDPNNBNFNJOSVCZ

Slide 42

Slide 42 text

Ripper.sexp('4 * a') # => [:program, # [[:binary, # [:@int, "4", [1, 0]], # :*, # [:vcall, [:@ident, "a", [1, 4]]]]]] Ripper.sexp program͔Β࢝·ΔϦετ ೋ෼໦ ਺஋Ϧςϥϧ ৐ࢉԋࢉࢠ ࣝผࢠ

Slide 43

Slide 43 text

Ripper.sexp('4 a') # => nil Ripper.sexp

Slide 44

Slide 44 text

Ripper.sexp class Ripper def Ripper.sexp(src, filename = '-', lineno = 1) builder = SexpBuilderPP.new(src, filename, lineno) sexp = builder.parse sexp unless builder.error? end # ... end DMBTT3JQQFSSVCZSVCZc(JU)VC
 IUUQTHJUIVCDPNSVCZSVCZCMPCGBCFYUSJQQFSMJCSJQQFSTFYQSC

Slide 45

Slide 45 text

ߏจղੳνΣοΫ 1. Ripper ʹ͔͚ͯߏจղੳ͕Ͱ͖Δ͔νΣοΫ module MathParser class MathRubyParser < MinRubyParser def mathruby_parse(program) converted_program = Ripper.sexp(program) ? program : reparse(program.strip) simplify(Ripper.sexp(converted_program)) end # ... end end

Slide 46

Slide 46 text

τʔΫϯνΣοΫ 2. Ͱ͖ͳ͚Ε͹਺஋ͱม਺͕ฒΜͰ͍ΔจࣈྻΛ୳͢ module MathParser::Converter def reparse(program) tokens = Ripper.lex(program) converted_program = convert(tokens) original_program = tokens.map{|token| token[2]}.join "" program.sub!(original_program, converted_program) Ripper.sexp(program).nil? ? reparse(program) : program end # ... end

Slide 47

Slide 47 text

module MathParser::Converter def convert(tokens) lines = [] tokens.last[0][0].times do |i| line_no = i + 1 previous_numeric = false line = [] tokens.map do |token| next if line_no > token[0][0] break if line_no < token[0][0] if space?(token) line << token[2] elsif currently_numeric?(token) && previous_numeric previous_numeric = true line << ["*", token[2]] else previous_numeric = currently_numeric?(token) line << token[2] end end lines << line.join("") end lines.join("") end # ... end ߦ൪߸ͷॳظԽ(1͔Β։࢝) ߦ൪߸͕ҧͬͨΒεΩοϓ line ʹτʔΫϯΛ௥Ճ

Slide 48

Slide 48 text

module MathParser::Converter def convert(tokens) lines = [] tokens.last[0][0].times do |i| line_no = i + 1 previous_numeric = false line = [] tokens.map do |token| next if line_no > token[0][0] break if line_no < token[0][0] if space?(token) line << token[2] elsif currently_numeric?(token) && previous_numeric previous_numeric = true line << ["*", token[2]] else previous_numeric = currently_numeric?(token) line << token[2] end end lines << line.join("") end lines.join("") end # ... end

Slide 49

Slide 49 text

τʔΫϯνΣοΫ 2. Ͱ͖ͳ͚Ε͹਺஋ͱม਺͕ฒΜͰ͍ΔจࣈྻΛ୳͢ module MathParser::Converter def currently_numeric?(token) ref_variable?(token) || int?(token) || float?(token) || rational?(token) end def ref_variable?(token) (token[1] == :on_ident) && (EXPR_END | EXPR_LABEL) == token[3]) end def int?(token) token[1] == :on_int end # ... end

Slide 50

Slide 50 text

τʔΫϯνΣοΫ 2. Ͱ͖ͳ͚Ε͹਺஋ͱม਺͕ฒΜͰ͍ΔจࣈྻΛ୳͢ module MathParser::Converter def currently_numeric?(token) ref_variable?(token) || int?(token) || float?(token) || rational?(token) end def ref_variable?(token) (token[1] == :on_ident) && (EXPR_END | EXPR_LABEL) == token[3]) end def int?(token) token[1] == :on_int end # ... end

Slide 51

Slide 51 text

module MathParser::Converter def convert(tokens) lines = [] tokens.last[0][0].times do |i| # ... tokens.map do |token| # ... if space?(token) line << token[2] elsif currently_numeric?(token) && previous_numeric previous_numeric = true line << ["*", token[2]] else previous_numeric = currently_numeric?(token) line << token[2] end end lines << line.join("") end # ... * ͷૠೖ 3. ਺஋ͱม਺ͷؒʹ * Λૠೖͯ͠ฦ͢

Slide 52

Slide 52 text

4. 1 ʙ 3 ͷ܁Γฦ͠ * ͷૠೖ module MathParser::Converter def reparse(program) tokens = Ripper.lex(program) converted_program = convert(tokens) original_program = tokens.map{|token| token[2]}.join "" program.sub!(original_program, converted_program) Ripper.sexp(program).nil? ? reparse(program) : program end # ... end

Slide 53

Slide 53 text

4. 1 ʙ 3 ͷ܁Γฦ͠ Ripper.lex '1 2 3 4 5' # => [[[1, 0], :on_int, "1", END], # [[1, 1], :on_sp, " ", END], # [[1, 2], :on_idt, "2", END]] γϯλοΫεΤϥʔʹͳΔͱlex్͕தͰऴྃ͢Δ * ͷૠೖ program.sub!(original_program, converted_program) Ripper.sexp(program).nil? ? reparse(program) : program

Slide 54

Slide 54 text

ܭࢉͷ࣮ߦ module MathParser class MathRubyParser < MinRubyParser def mathruby_parse(program) converted_program = Ripper.sexp(program) ? program : reparse(program.strip) simplify(Ripper.sexp(converted_program)) end # ... end end 5. * ͕ૠೖ͞Εͨߏจ໦Λ࣮ߦ (ܭࢉ) ͢Δ minruby ͷఏڙϝιου
 ߏจ໦Λऔಘͯ͘͠ΕΔ

Slide 55

Slide 55 text

ܭࢉͷ࣮ߦ 5. * ͕ૠೖ͞Εͨߏจ໦Λ࣮ߦ (ܭࢉ) ͢Δ module MathParser def evaluate(tree, genv, lenv) case tree[0] when "lit" tree[1] when "+" evaluate(tree[1], genv, lenv) + evaluate(tree[2], genv, lenv) when "-" evaluate(tree[1], genv, lenv) - evaluate(tree[2], genv, lenv) when "*" evaluate(tree[1], genv, lenv) * evaluate(tree[2], genv, lenv) when "/" evaluate(tree[1], genv, lenv) / evaluate(tree[2], genv, lenv) when "**" evaluate(tree[1], genv, lenv)**evaluate(tree[2], genv, lenv) when "%" evaluate(tree[1], genv, lenv) % evaluate(tree[2], genv, lenv) when "<" evaluate(tree[1], genv, lenv) < evaluate(tree[2], genv, lenv) when "<=" evaluate(tree[1], genv, lenv) <= evaluate(tree[2], genv, lenv) when ">" # ... 3VCZͰͭ͘Δ3VCZθϩ͔Βֶͼͳ͓͢ϓϩάϥϛϯάݴޠೖ໳cԕ౻ါհ
 IUUQTXXXMBNCEBOPUFDPNQSPEVDUTSVCZSVCZ evaluate ϝιου͸
 Ruby Ͱͭ͘Δ Ruby ͷ಺༰΄΅ͦͷ··

Slide 56

Slide 56 text

࣮ߦͯ͠ΈΔ

Slide 57

Slide 57 text

Ͱ͖ͨʂʂ irb(main):001:0> require ‘math_parser' => true irb(main):002:0' mp ' irb(main):003:0' a = 2 irb(main):004:0' c = 3 irb(main):005:0' 4 a c irb(main):006:0> ' => 24

Slide 58

Slide 58 text

irb(main):001:0> require ‘math_parser' => true irb(main):002:0' mp ' irb(main):003:0' a = 2 irb(main):004:0' c = 3 irb(main):005:0' a 4 c irb(main):006:0> ' Ͱ͖ͯͳ͍ ϝιουݺͼग़͠ͱͯ͠ղऍ͞ΕΔ NoMethodError (undefined method `[]' for nil:NilClass)

Slide 59

Slide 59 text

module MathParser def evaluate(tree, genv, lenv) case tree[0] # ... when "func_call" args = tree[2..].map { |t| evaluate(t, genv, lenv) } # ૊ΈࠐΈؔ਺ if respond_to?(tree[1]) || Kernel.respond_to?(tree[1]) send(tree[1], *args) # Ϣʔβఆٛؔ਺ elsif genv.has_key? tree[1] func_lenv = {} mhd = genv[tree[1]] params = mhd[1] params.each_with_index { |param, j| func_lenv[param] = args[j] } evaluate(mhd[2], genv, func_lenv) # ະఆٛͷ৔߹͸ tree Λมߋͯ͠࠶౓ evaluate ͢Δ else new_tree = ["*", ["var_ref", tree[1]], tree[2]] evaluate(new_tree, genv, lenv) end # ... end end end 5. * ͕ૠೖ͞Εͨߏจ໦Λ࣮ߦ (ܭࢉ) ͢Δ Ϣʔβఆٛؔ਺Λొ࿥

Slide 60

Slide 60 text

Ͱ͖ͨʂʂ irb(main):001:0> require ‘math_parser' => true irb(main):002:0' mp ' irb(main):003:0' a = 2 irb(main):004:0' c = 3 irb(main):005:0' a 4 c irb(main):006:0> ' => 24

Slide 61

Slide 61 text

Ͱ͖ͯͳ͍ ͪΌΜͱͨ͠ΤϥʔΛ
 ฦ͢Α͏ʹ͍ͨ͠ͳ͋ ෼਺ͱ͔ྦྷ৐ͱ͔
 ΋ͬͱײ֮తʹ
 ॻ͚ΔΑ͏ʹ͍ͨ͠ͳ͋ ϝιου಺Ͱ͔͠ม਺
 ͍֮͑ͯΒΕͳ͍ ͙͢Τϥʔग़Δ irb Έ͍ͨͳ REPL ্Ͱ
 ϝιουհͣ͞
 ࣮ߦͰ͖ΔΑ͏ʹ͍ͨ͠ ●ɹ● ָ͠Έ

Slide 62

Slide 62 text

ߏจղੳ͸ා͘ͳ͍ ΊͪΌͪ͘Ό஍ಓ Ruby ͍͢͝ Did you mean? ͍͢͝ ͍͢͝΋ͷ͍ͬͺ͍͋Δ ·ͱΊ

Slide 63

Slide 63 text

ࣗ෼Ͱ࢖͏ಓ۩
 ͭ͘Δͷָ͍͠ʂ ·ͱΊ

Slide 64

Slide 64 text

Special Thanks Ruby Ͱͭ͘Δ Ruby | ԕ౻ ါհ (@mame) 
 https://www.lambdanote.com/products/ruby-ruby minruby | ԕ౻ ါհ (@mame) 
 https://github.com/mame/minruby

Slide 65

Slide 65 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠