Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Crystal*macro

yui-knk
August 01, 2015

 Crystal*macro

Slides for 東京 Crystal 勉強会 #1 in 五反田

yui-knk

August 01, 2015
Tweet

More Decks by yui-knk

Other Decks in Programming

Transcript

  1. ϚΫϩ?? • Macros are methods that receive AST nodes at

    compile-time and produce code that is pasted into a program. • ίϯύΠϧ࣌ʹɺASTϊʔυΛ͏͚ͱͬͯɺ ίʔυΛฦ͢Α͏ͳϝιουɻ • http://crystal-lang.org/docs/syntax_and_semantics/macros.html
  2. Example.1 # ϚΫϩΛఆٛ͢Δ macro define_method(name, content) def {{name.id}} {{content}} end

    end ! # ϚΫϩΛల։͢Δ define_method :foo, 1 # def foo # 1 # end ! # ϝιουΛݺͼग़͢ foo # => 1
  3. Example.2 (for) # ϚΫϩΛఆٛ͢Δ macro define_dummy_methods(names) {% for name, index

    in names %} def {{name.id}} {{index}} end {% end %} end ! # ϚΫϩΛల։͢Δ define_dummy_methods [foo, bar, baz] # def foo # 0 # end # … ! foo # => 0 bar # => 1 baz # => 2
  4. Example.3 (yield) # ϚΫϩΛఆٛ͢Δ macro test_with p "before" {{yield}} p

    "after" end ! # ϚΫϩΛల։͢Δ test_with do p "in block" end # p "before" # p "in block" # p "after"
  5. ϚΫϩ?? • Macros are methods that receive AST nodes at

    compile-time and produce code that is pasted into a program. • ίϯύΠϧ࣌ʹɺASTϊʔυΛ͏͚ͱͬͯɺ ίʔυΛฦ͢Α͏ͳϝιουɻ • http://crystal-lang.org/docs/syntax_and_semantics/macros.html
  6. Example.4 # ϚΫϩΛఆٛ͢Δ macro test_print {{p "before"}} {{yield}} {{p "after"}}

    end ! # ϚΫϩΛల։͢Δ test_print do p "in block" end # “before" (printed) # “after" (printed) # # p "in block" # ϚΫϩల։࣌ʹQSJOUͯ͠OJMΛฦ͢
  7. ϚΫϩ?? • Macros are methods that receive AST nodes at

    compile-time and produce code that is pasted into a program. • ίϯύΠϧ࣌ʹɺASTϊʔυΛ͏͚ͱͬͯɺ ίʔυΛฦ͢Α͏ͳϝιουɻ • http://crystal-lang.org/docs/syntax_and_semantics/macros.html
  8. Example.5 (StringLiteral) # ͜Ε͸ok {{"hoge".upcase}} # "HOGE" ! # ͜Ε͸ok

    "1".to_i # =>1 ! # ͜Ε͸ng {{"1".to_i}} ! Error in test.cr:1: expanding macro ! {{"1".to_i}} ^ ! in test.cr:1: undefined macro method 'StringLiteral#to_i' ! {{"1".to_i}} ^~~~
  9. Example.6 (#class_name) from 0.7.5 macro print_class_names(*nodes) {% for node in

    nodes %} {{p node.class_name}} {% end %} end ! print_class_names(“1") # “StringLiteral" print_class_names([1]) # “ArrayLiteral" print_class_names({a: 10}) # “HashLiteral" print_class_names(foo) # “Call" print_class_names(true ? 1 : 0) # “If"
  10. Example.6 (#class_name) from 0.7.5 print_class_names( if true 1 else 0

    end ) # “If" print_class_names( class Foo end ) # “ClassDef" print_class_names( def test_method end ) # “Def"
  11. Example.6 (#class_name) from 0.7.5 print_class_names( if true 1 else 0

    end, class MyClass end ) # “If" # “ClassDef"
  12. Example.7 (my_unless) macro my_unless(cond, then_exp, else_exp = nil) if {{

    cond }} {{ else_exp }} else {{ then_exp }} end end ! def ten?(a) a == 10 end ! my_unless( ten?(11), p("false case"), p("true case") ) # "false case"
  13. Example.8 (visibility) class MyClass def public_method end ! protected def

    protected_method end ! private def private_method end ! {% for m in @type.methods %} {{p m.name}} {{p m.visibility}} {% end %} end # public_method # :public # protected_method # :protected # private_method # :private
  14. ·ͱΊ • ruby like syntaxͰcompilerͱ͔ಡΊΔ • macro def ͱ͔ @type

    ͷ͜ͱௐ΂͍ͨ • ASTNodeͷprinter΄͍͠ • ύʔαδΣωϨʔλʔɾɾɾ