5

Smalltalk(特別是Squeak/Pharo)具有某種形式的可變參數函數嗎?Smalltalk可變參數函數

我只是在閱讀有關在smalltalk中設計自己的控制語句的權力,而我是ifTrue的忠實粉絲:ifFalse:我很難想出實現任意if的好方法if否則,如果其他,...,否則陳述思考如何有用Variadic功能這些將用於實施案件陳述。喜歡的東西

假類

ifTrue: aBlock (... elseIf: aBoolean then: aSecondBlock ...) else: aLastBlock 

vArgList pairsDo: [:x :y| x ifTrue:[^ (y value)] ]. 
^ aLastBlock 

回答

1

可以使用#caseOf:otherwise:消息。 尋找這個消息的一些發送者的一些例子。

但無論如何,如果你想使用case語句,你不會遵循smalltalk-way-of-doing-things。告訴我們您的案例陳述要實現的目標,以便我們向您展示一些更乾淨的方法。

+0

作爲一般原則,我同意。對於Andreas Raab在DnsClient(在SqueakSource上)使用#caseOf:otherwise:來說,我很難看出如何改進可讀性。 – 2010-10-12 09:21:55

3

Smalltalk的關鍵字樣語法方法調用本質定義方法的參數數量。沒有像Common Lisp那樣的&rest模式。

你當然可以採取一個列表,如BlockClosure>>valueWithArguments:,但這是幾乎不一樣的事情。

您可以修改Compiler以支持可變方法調用。也許呼叫只會有每個變量之間with:

(條件)ifTrue:ABLOCK ELSEIF:aBoolean有:aSecondBlock有:anotherBoolean有:aThirdBlock

+0

您不能只修改編譯器。您還需要修改虛擬機。因爲參數的數量在BlockClosure中,它告訴了要創建的上下文的大小(包括參數的數量)。 – mathk 2010-10-11 21:06:51

1

一個我在編程學到的東西是不是你不需要case語句,你不想 case語句。

Case語句是膨脹對象的方式。當你使用它時,你會降低維護。當時你將擁有所有你想要的可能性,但是當你想添加某些東西時,如果不再記得該對象責任的微妙之處,就必須查看令人討厭的代碼,所以你會臃腫不堪更。

在很短的時期內,他們看起來很友善,但個案陳述不是你的朋友。從長遠來看,他們會咬你的。

此外,他們讓你的代碼更不靈活。例如,你不能自信地添加一個關於前面的代碼的案例。當你不記得它時,你不得不復習舊的代碼,爲什麼它是這樣編碼的。

案例陳述是好代碼的敵人。

如果你有什麼超越ifTrue:ifFalse:那麼正確的做法是爲此做出狀態。所以你要做的是實現三個非常簡單的類,他們都理解一些動詞。

說,#doTheNextThing。因此,當對象收到它委託給狀態的消息時(以三者中的一個爲準),並且狀態知道如何使原始接收器正確反應。

這將使您的代碼輕鬆,明顯且高度可維護。你將能夠忘記這一點,因爲你知道,當你再次看到它時,一切都非常明顯,你不需要像以後的代碼那樣考慮代碼的過去。

這很重要,因爲您的記憶體是您擁有的最昂貴的記憶,而且AFAIK不可升級。所以這個技巧可以讓你做更強大的東西。

除此之外,製作3個班級可能聽起來像一些更多的工作,但不是。任何noob都可以在眨眼的時候添加3個空類,但只有正確的專家纔會記住舊代碼中的case語句是如何按照它的方式創建的。如果你非常樂觀,那麼需要幾分鐘的時間才能回憶起來,所以你們都知道下一步該做什麼。考慮一下。