所以我正在构建一个数据类型
可选自动铸造
.
The last question I asked is related to this also.
我目前拥有的代码可以在下面找到:
class Test(T)
@@auto_cast = false
def initialize(var : T)
@var = var
end
def self.auto_cast
@@auto_cast
end
def self.auto_cast=(val)
@@auto_cast = val
end
def self.auto_cast(forced_value=true,&block)
#Force value, but store initial value:
ac = @@auto_cast
@@auto_cast = forced_value
block.call
@@auto_cast = ac
end
def +(val)
var = @var
if @@auto_cast
if var.is_a? String
casted_arg = val.to_s
return var + casted_arg
else
casted_arg = typeof(var).new(val)
return var + casted_arg
end
else
if typeof(var) != typeof(val)
{{raise "Error: Type of <<var>> is not equal to type of <<val>> while auto_cast is false."}}
else
return var + val
end
end
end
end
但是,当我尝试测试数据类型时:
Test.auto_cast do
puts Test.auto_cast
puts Test.new(1) + "1"
puts Test.new("1") + 1
end
它在
return var + val
以下内容:
if typeof(var) != typeof(val)
{{raise "Error: Type of <<var>> is not equal to type of <<val>> while auto_cast is false."}}
else
ERROR! --> return var + val
end
起初我很困惑为什么,但现在它是有意义的。
-
我相信水晶编译器不能确定
@@auto_cast
每当我打算自动转换时都是正确的(公平地说,当禁用自动转换时,我希望出现语法错误)。
-
出现编译错误,因为
@@自动铸造
在编译时未知。
-
由于身体的矛盾性:
.
if var.is_a? String
casted_arg = val.to_s
return var + casted_arg
else
casted_arg = typeof(var).new(val)
return var + casted_arg
end
和
if typeof(var) != typeof(val)
{{raise "Error: Type of <<var>> is not equal to type of <<val>> while auto_cast is false."}}
else
return var + val
end
每个定义只应在用户显式声明时使用。因此,这更适合于宏。
鉴于这些原因,我开始尝试将功能构建成宏:
def +(val)
var = @var
{%if @@auto_cast%}
if var.is_a? String
casted_arg = val.to_s
return var + casted_arg
else
casted_arg = typeof(var).new(val)
return var + casted_arg
end
{%else%}
if typeof(var) != typeof(val)
{{raise "Error: Type of <<var>> is not equal to type of <<val>> while auto_cast is false."}}
else
return var + val
end
{%end%}
end
我认为这是可行的,因为只有在
@@自动铸造
已设置。然而,我忘记的是前提2。即
@@自动铸造
在编译时未知。最终,为了实现这一目标,我需要一个变量,它可以是:
-
在编译时设置。
-
在编译时在宏中全局使用。
最后,我想我可以做些事情:
SET_AUTOCAST_VARIABLE true
puts Test.auto_cast
puts Test.new(1) + "1"
puts Test.new("1") + 1
SET_AUTOCAST_VARIABLE false
然后在
+()
定义:
{%if autocast_variable %}
...
{%else%}
...
{%end%}
问题是,我不认为
宏全局变量
存在。。。我在考虑如何解决这个问题,到目前为止,我能想到的唯一解决方案是在编译时使用一些外部文件:
{{File.write("/tmp/cct","1")}}
puts Test.auto_cast
puts Test.new(1) + "1"
puts Test.new("1") + 1
{{File.write("/tmp/cct","")}}
在方法定义中:
{%if File.read("/tmp/cct")=="1" %}
...
{%else%}
...
{%end%}
不过这感觉很糟糕…我想知道是否还有其他的选择(或者,甚至,如果这根本不起作用的话)?