链接关键字消息

lur*_*ker 8 smalltalk

让我们假设我有一个对象,x,它可以接受的选择中的任何一个,s1,s2,..., sn.让我们进一步假设在对象上操作的这些选择器中的任何一个的结果是相同类型的更新对象.然后,我可以按照我的意愿"链接"这些选择器(只要它们是一元消息),例如:

x s1 s2 ... sn
Run Code Online (Sandbox Code Playgroud)

这将获取结果x s1和应用选择器s2,然后将选择器s3应用于该结果,依此类推.我想以某种顺序应用这些选择器中的一个或多个以获得各种结果:

x s8 s2
Run Code Online (Sandbox Code Playgroud)

在Smalltalk中,如果选择器是一元消息,我可以这样做.但是,如果我的选择器是关键字消息,我就不能再这样做了.如果x单独接受选择,s1:,s2:,... sn:,那么下面不工作:

x s1: a1 s2: a2 ... sn: an
Run Code Online (Sandbox Code Playgroud)

;运营商:

x s1: a1 ; s2: a2 ; ... ; sn: an
Run Code Online (Sandbox Code Playgroud)

但是使用级联:每个阶段都会修改原始版本x,我不希望x在这种情况下进行修改.

为了链接关键字消息,我想我在括号中使用了以下语法:

(...(((x s1: a1) s2: a2) ... sn: an)
Run Code Online (Sandbox Code Playgroud)

如果我有3个或更多的keywrod消息,这让我觉得我在LISP编程.这个的具体例子可以是多维数组.如果foo是一个三维数组,并且你想访问数组中2,3,5位的对象,我认为它看起来像:

(((foo at: 2) at: 3) at: 5) some_object_selectors
Run Code Online (Sandbox Code Playgroud)

当然,这是一个微不足道的例子,但说明了这种情况.可能有其他类型的嵌入对象,或者您对最终结果感兴趣的其他连续对象操作链.

在Smalltalk中有更多的语法上有吸引力的方法吗?我假设没有其他操作员,也许是操作员的表兄;(例如我们使用&),它们将链接它们,例如:

x s1: a1 & s2: a2 & ... & sn: an
Run Code Online (Sandbox Code Playgroud)

由于我想以任何或几乎任何所需的顺序(可能是不同的结果)应用选择器,因此选择器形式s1:s2:s3:...太局限了.此外,这提供了一种已经存在于其他语言中的工具,例如Ruby,它可以等效地表示为:

x.s1(a1).s2(a2)...sn(an)
Run Code Online (Sandbox Code Playgroud)

缺少一个特殊的运算符,另一种方法是传递一个选择器 - 参数对的数组,或者可能是一个选择器 - 参数对的查找表.查找表需要设置传递文字(必须创建和填充),这使我倾向于数组,因为我可以简单地将其写为:

x { {s1. a1}. {s2. a2}. ... {sn. an} }
Run Code Online (Sandbox Code Playgroud)

这仍然有点笨重,我不太确定这比使用所有括号更优雅.我担心我的问题可能至少部分是主观的,但我很想知道最佳实践可能是什么,以及运营商是否存在我不知道哪些可能会有所帮助,或者是否有人受到Smalltalk的欢迎标准机构.

Amo*_*ter 8

这里似乎有些混乱.

  1. 级联是使用;,其中每条消息都发送到同一个参数.
  2. 您的x s1 s2...示例(您称之为"级联")称为消息链接,其中每条消息都被发送到上一条消息的结果(由于Smalltalk语法的美丽和优雅的性质,它简单Object message且始终返回结果).不,你不能总是把它们放在任何顺序.想象s1multiplyByTwos2addTwo,与x具有由这些方法启动作为改性一个实例变量1.订单可能很重要.(请注意,我非常不愿意使用这些非常简短的名字作为例子 - 它不像Smalltalk那样.;-)
  3. 如果你的n身材太大以至于使用括号使它看起来很尴尬,那么,呃...对不起,但是你做错了.
    • 考虑在对象上创建一个接受多个参数的方法.
    • 考虑创建一个包装器对象来携带您的参数.
    • 考虑使用设计模式将对象与要对其执行的操作分离.(你需要哪种模式取决于你想要达到的目标; 这是一个很好的起点.)

而不是寻找操作员将Smalltalk弯曲到你的意愿(你可能习惯用其他语言做事),我建议弯曲到Smalltalk的意愿(显式命名,不要害怕创建更多的对象和方法,等等.).从长远来看,你会从中获得更多,我敢说你会希望其他语言具有Smalltalk的简单性和强大功能.


Ste*_*ont 1

通常我们给这个对象 xa 一个主题来进行操作,然后在完成操作后请求这个改变的主题。复制效率相当低。

Object subclass: #Foo
    instanceVariableNames: 'subject'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Try'

order: y
    self subject order: y

select: z
    self subject select: z

subject
    ^subject ifNil: [ subject := FooSubject new ]

where: x
    self subject where: x
Run Code Online (Sandbox Code Playgroud)