【发布时间】:2019-10-16 18:28:37
【问题描述】:
最近我在为自定义记录类型提供自己的替换'Write () 过程时取得了巨大的成功,例如...
type Pixel_Format is
record
-- blah blah
end record;
procedure Pixel_Format_Write (
Stream : not null access Root_Stream_Type'Class;
Item : in Pixel_Format);
for Pixel_Format'Write use Pixel_Format_Write;
在写入网络流时,我使用它来将某些记录成员从小端转换为大端。效果很好。
出于同样的想法,我想知道是否可以替换十进制定点类型的'Round () 函数,所以我尝试了一个快速而肮脏的测试......
-- This is a "Decimal Fixed Point" type
type Money_Dec_Type is delta 0.001 digits 14;
-- ...
function Money_CustomRound(X : in Money_Dec_Type)
return Money_Dec_Type'Base;
for Money_Dec_Type'Round use Money_CustomRound; -- COMPILER COMPLAINS HERE
-- ...
function Money_CustomRound(X : in Money_Dec_Type)
return Money_Dec_Type'Base is
begin
return 0.001;
end Money_CustomRound;
唉,GNAT 觉得这很冒犯:
attribute "Round" cannot be set with definition clause
问题:
我在尝试不可能的事情吗?或者有没有办法改变默认的'Round 属性,就像改变'Write 一样?
问题的背景:
我有一组大约 15 种不同的四舍五入货币值的方法,这些方法从一个项目到另一个项目(有时在同一个项目中!)。示例包括:
- 从零开始取整(似乎是 Ada 的默认值)
- 向零取整
- 统计(需要全局管理的可重入类型)
- 轮到偶数或赔率
- 向 +INF / -INF 舍入
- ...
通过使用在通用包级别定义的某些舍入方法,能够使这种功能对程序员透明,这将是一个强大的工具。
我另一个肩膀上的天使暗示我在要求一些完全疯狂的东西。
我想知道这是因为文档(ALRM 和“Barnes 2012”)都给出了默认过程的功能规范。如果一个人不能用自己的设计替换它,他们为什么要这样做?
【问题讨论】:
-
无论如何您都必须编写代码,那么重新定义属性而不是仅仅拥有一个函数
Round有什么好处呢? ...实际上最终会得到更短的代码 -
@SimonWright,使用旧默认行为的现有函数不必针对新要求进行修改。
-
在进行移植/重构时,我经常遇到这种对查找替换代码的“恐惧”。我经常认为这是管理层对开发人员和软件演变缺乏信心的象征。即使我你可以重新定义 le ‘Round,你也必须评估(测试)它对所有用户的影响。无论如何都会进行影响分析和测试。为什么然后让«打开+编辑»n个文件成为一个可怕的事件?软件会随着时间的推移而变化,无论人们多么不希望它发生变化。
-
@LoneWanderer,是的,你是对的。我希望这也不是一个症结所在。我也希望我有能力对此做任何事情:)
-
@LoneWanderer 并不总是害怕,还有一个简单的便利因素。如果它“刚刚发生”,那么您就没有做额外的工作。
标签: rounding ada fixed-point