2017-01-10 37 views
2

水晶行为,我创建这个类:与变量assignement

1. class Component 
2. 
3. getter :content, :htm_options, :options 
3. 
4. @html_options : Hash(Symbol | String, Symbol | String) 
5. @options  : Hash(Symbol | String, Symbol | String) 
6. @content  : String 
7. 
8. def initialize(c = nil, o = nil, h = nil, block = nil) 
9.  if false #!block.nil? 
10.  @html_options = o unless o.nil? 
11.  @options  = c unless c.nil? 
12.  context = eval("self", block.binding) 
13.  @content = context.capture(&block) 
14.  else 
15.  if c.is_a?(Hash) 
16.   @html_options = o unless o.nil? 
17.   @options  = c unless c.nil? 
18.  else 
19.   @html_options = h unless h.nil? 
20.   @options  = o unless o.nil? 
21.   @content  = c unless c.nil? 
22.  end 
23.  end 
24. end 
25. end 

Component.new("My text") 

我有一个错误:

in src/ui_bibz/ui/core/component.cr:11: instance variable '@options' of Component must be Hash(String | Symbol, String | Symbol), not String 
@options = c unless c.nil? 

我不理解这种行为,因为我没有在if条件通过。我想根据几种情况分配@htm_options, @options, @content。 是否可以声明一个已经声明过的变量?

回答

3

恐怕在检查类型时,编译器有时不够聪明,无法检测哪些路径被采用,哪些不是。因此,在第11行中,编译器发现您正在尝试将一个String分配给之前定义为Hash的变量,并且失败。

至于你的问题,恐怕不可能重新声明一个实例变量。如果你想要@options同时保存一个字符串或哈希,你可以声明它是一个哈希和字符串的联合。

+0

这很烦人:(谢谢 – Thooams

+0

因为后,我有一个哈希合并@options的方法,但编译器提醒我有一个错误:'找不到重载对于这些类型:Hash(Symbol,Symbol)#merge(other:String)'。这是正常的,因为我定义了@options就像一个哈希和字符串的联合。没有解决方案!! :( – Thooams

+1

总有一个解决方案或破解会工作,但Crystal是静态类型的,使用完全不同类型的工会通常最终会非常烦人。也许你可以重新思考你的API,所以选项总是一个例如'哈希(字符串,字符串)'? –

0

水晶是打字的,这是一件好事,但对我而言,我想重新定义我的变量。我的代码像ruby中的“link_to”一样工作。组件必须以不同的方式写入。有时候,内容会被变量填充,有时会被块填充。初始化方法将以不同的方式填充。有一种方法可以通过宏或其他解决方案重新定义变量?

class Component < UiBibz::Ui::Base 

    getter :content, :htm_options, :options 

    def initialize(c = nil, o = nil, h = nil, block = nil) 
    if !block.nil? 
     html_opts, opts = o, c 
     context = eval("self", block.binding) 
     @content = context.capture(&block) 
    else 
     if c.is_a?(Hash) 
     html_opts, opts = o, c 
     else 
     html_opts, opts, cont = h, o, c 
     end 
    end 
    @html_options = html_opts || {} of Symbol => Symbol | String 
    @options  = opts  || {} of Symbol => Symbol | String 
    @content  = content 
    end 
end 

# 1 way 
Component.new("My content", { :option_1 => true }, { :class => "red" }) 

# 2 way 
Component.new({ :option_1 => true }, { :class => "red" }) do 
    "My content" 
end   

错误:

in src/ui_bibz/ui/core/component.cr: instance variable '@options' of Component must be Hash(Symbol, String | Symbol), not (Hash(Symbol, String | Symbol) | String) 
@options = opts || {} of Symbol => Symbol | String 
+0

有人吗?请:( – Thooams

+0

我找到了我的答案!https://blog.codeship.com/crystal-from-a-rubyists-perspective/ 我必须重写初始化方法。 – Thooams