宏
宏是一些预编译的方法(在编译时被加入到抽像语法树中),这些方法必须是完整有效的Crystal代码。
macro define_method(name, content)
def {{name}}
{{content}}
end
end
# This generates:
#
# def foo
# 1
# end
define_method foo, 1
foo #=> 1
宏作用域
宏被定义在顶层作用域,所有代码中都可用。如果某个宏被标记为private 那么它只在当前文件中可见。宏也可以定义在类和模块中, 并且在定义它的作用域中可见。程序也会在先祖域中搜索宏(父类 及被包含的模块中)。For example, a block which is given an object to use as the default receiver by being invoked with with … yield can access macros defined within that object’s ancestors chain:
class Foo
macro emphasize(value)
"***#{ {{value}} }***"
end
def yield_with_self
with self yield
end
end
Foo.new.yield_with_self { emphasize(10) } #=> "***10***"
定义在类中或模块中的宏 也可以在外部被调用。
class Foo
macro emphasize(value)
"***#{ {{value}} }***"
end
end
Foo.emphasize(10) # => "***10***"
插值
使用 {{…}} 在语法树中进行插入值。
宏调用
你可以在编译时调用一些方法, 这些方法被定义在Crystal::Macros 模块中。
条件语句
# 你可以使用{% if condition %} ... {% end %} 来按条件生成代码。宏的条件语句可以在宏定义之外的地方使用。
macro define_method(name, content)
def {{name}}
{% if content == 1 %}
"one"
{% else %}
{{content}}
{% end %}
end
end
define_method foo, 1
define_method bar, 2
foo #=> one
bar #=> 2
迭代
迭代语句也可以在宏定义之外的地方使用。
macro define_dummy_methods(names)
{% for name, index in names %}
def {{name.id}}
{{index}}
end
{% end %}
end
define_dummy_methods [foo, bar, baz]
foo #=> 0
bar #=> 1
baz #=> 2
#
macro define_dummy_methods(hash)
{% for key, value in hash %}
def {{key.id}}
{{value}}
end
{% end %}
end
define_dummy_methods({foo: 10, bar: 20})
foo #=> 10
bar #=> 20
#
{% for name, index in ["foo", "bar", "baz"] %}
def {{name.id}}
{{index}}
end
{% end %}
foo #=> 0
bar #=> 1
baz #=> 2
宏方法定义
todo
钩子
在一些场景下,一些特殊的宏被当成钩子来使用。这些场景是 inherited, included, extended 和 method_missing
1.inherited在编译时被触发,如果定义了子类。@type is the inheriting type.
2.included在编译时被触发,当一个模块被include时。@type is the including type.
3.extended在编译时被触发,当一个模块被extend时。@type is the extending type.
4.method_missing 在编译时被触发,当方法不存在时.
例子: inherited
class Parent
macro inherited
def lineage
"{{@type.name.id}} < Parent"
end
end
end
class Child < Parent
end
Child.new.lineage #=> "Child < Parent"
例子: method_missing
macro method_missing(call)
print "Got ", {{call.name.id.stringify}}, " with ", {{call.args.size}}, " arguments", '\n'
end
foo # Prints: Got foo with 0 arguments
bar 'a', 'b' # Prints: Got bar with 2 arguments
变量刷新
//todo
当前内容版权归 crystal-lang中文站 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 crystal-lang中文站 .