簡體   English   中英

如何覆蓋另一個包中的類中的現有選擇器

[英]How to override an existing selector in a class in another package

我正在使用Pharo 5.0。 在某些情況下,我在現有的Pharo類中發現了一個限制,或者可能是一個錯誤( 例如 ,DBXTalk / Garage或Regex-Core中的某個東西)。 我希望能夠修改我自己項目之外的類中存在的一個選擇器或一組選擇器,並將其作為包的一部分。

我找到了一些有關如何在外部類中創建選擇器並將其移入我的包的說明( 例如 ,如本教程所示)。 太酷了。 但是在某些情況下,我實際上想修改外部類中的現有選擇器,並在使用時讓該選擇器的副本覆蓋外部類中的選擇器。 我不希望修改現有的第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”書籍中。

請注意,除了Milan Vavra編寫的內容外,名為*YourPackage-(something)的協議中的每個方法都將屬於YourPackage包,而與該類所屬的包無關。 至少在Squeak中,有一種約定將放置被*YourPackage-override協議*YourPackage-override Pharo可能具有類似的命名約定。 移至程序包功能會將方法移至“加星標”協議。

但是,不建議使用此類替代,因為您不能讓兩個包同時為同一方法提供一個實現。 Monticello將嘗試同時保留原始方法和覆蓋方法(請參見PackageInfo>>isOverrideCategory:發件人),但是仍然有可能通過更新其原始包來覆蓋您的覆蓋方法,否則您將錯過對原始方法的更新,可能會破壞事情。

“正確的方法”是重構原始程序包中的原始方法,以使其行為更易於自定義。

GNU Smalltalk語法中的代碼

Kernel.MatchingRegexResults extend [
    at: anIndex [
        "method body"
    ]
    foo [
        "My new foo selector"
    ]
]

看起來像這樣

!MatchingRegexResults methodsFor: 'protocol'!
at: anIndex 
    "method body"
!
foo
    "My new foo selector"
! !

可以從文件瀏覽器歸檔的Pharo更改集中。

但是請注意,在兩種情況下,GNU Smalltalk和Pharo Smalltalk都實際上是在替換該類中方法的原始版本。

在GNU Smalltalk中,您可能不習慣保存圖像,因此您可能會認為擴展語法不會修改原始類中的原始方法。

實際上,它確實做到了。

使用GNU Smalltalk,通常每次運行gst時都從相同的舊未修改映像開始。 這是因為普通用戶不能寫GNU Smalltalk中圖像的默認位置。 因此,gst每次都會讀取相同的只讀映像,您可以使用類定義和擴展在內存中對其進行修改,修改后的映像僅在程序運行時臨時存在,並在程序退出時被丟棄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM