我正在使用Pharo 5.0。在某些情况下,我发现现有Pharo类中存在限制或可能存在错误(例如,DBXTalk / Garage或Regex-Core中的某些内容)。我希望能够修改我自己项目之外的类中存在的选择器或选择器集,并将其作为我的包的一部分。
我找到了一些关于如何在外部类中创建 new 选择器的说明,并将其移到我的包中(例如,如此{{3}所示) })。这非常酷。但在某些情况下,我实际上想修改外部类中的现有选择器,并且当我使用它时,我的该选择器的副本会覆盖外部类中的那个。我不希望修改现有的第三方或Pharo预先提供的包。
在GNU Smalltalk中,我可以将其作为进行类扩展的正常部分。例如:
Kernel.MatchingRegexResults extend [
at: anIndex [
"My updated version of the 'official' Kernel.MatchingRegexResults#at: selector"
"This is part of my package so overrides the 'official' version"
...
]
foo [
"My new foo selector"
]
]
如何在Pharo 5.0中执行此操作?我做了很多搜索,但找不到办法。单词"延伸"或"覆盖"不会出现在 Pharo by Example 和 Deep Into Pharo 书籍中。
答案 0 :(得分:3)
请注意,除了Milan Vavra所写的内容之外,名为*YourPackage-(something)
的协议中的每个方法都属于包YourPackage
,无论该类属于哪个包。至少在Squeak中,有一种惯例是在*YourPackage-override
协议中将方法重写为这样。 Pharo可能有类似的命名约定。 Move to package功能将方法移动到这种“已加星标”的协议。
但是,不鼓励使用此类覆盖,因为您不能让两个包同时为同一方法提供实现。 Monticello将尝试保留原始方法和重写方法(请参阅PackageInfo>>isOverrideCategory:
的发件人),但仍有可能您的覆盖方法将被原始包的更新覆盖,否则您将错过原始方法的更新,可能会破坏事物。
“正确的方法”是重构原始包中的原始方法,以使其行为更容易定制。
答案 1 :(得分:2)
GNU Smalltalk语法中的代码
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int a = 0;
printf("Enter a number: ");
scanf ("%d" ,&a);
printf ("%d \n ",a);
return 0;
}
看起来像这样
Kernel.MatchingRegexResults extend [
at: anIndex [
"method body"
]
foo [
"My new foo selector"
]
]
在Pharo更改集中,可以从文件浏览器中归档。
但请注意,在两种情况下,GNU Smalltalk和Pharo Smalltalk,您实际上都在替换该类中方法的原始版本。
在GNU Smalltalk中,您可能不习惯保存图像,因此您可能认为extend语法不会修改原始类中的原始方法。
实际上确实如此。
使用GNU Smalltalk,每次运行gst时,通常都会使用相同的旧的未修改图像。 这是因为GNU Smalltalk中图像的默认位置不能写入普通用户。因此gst每次都读取相同的只读图像,您可以使用类定义和扩展在内存中修改它,修改后的图像仅在程序运行时暂时存在,并在程序退出时被丢弃。