Squeak Smalltalk- 如何使 "Transcript show" 打印更多东西?
Squeak Smalltalk- How to make to "Transcript show" print more things?
我正在使用 Smalltalk 输入 Transcript window 1-9 乘法 table .
这是我的代码:
1 to: 9 do: [:i|
1 to: i do: [:j|
Transcript show: j.
Transcript show: ' * '.
Transcript show: i.
Transcript show: ' = '.
Transcript show: j * i.
Transcript show: ' '.
].
Transcript show: ' '; cr.
].
可以看出,上面的代码虽然工作正常,但看起来远非美观和简洁。
我曾希望写这样的东西:
Transcript show: j '*' i '=' j * i.
不幸的是,他们错了。我记得 C 有一个很好的方法来处理我的那个问题。
喜欢,printf("%d * %d = %d ", j, i, j * i);
在这种情况下,是否有更优雅的方法使 Smalltalk 代码更优雅?
Peter 解决了这个问题。谢谢。
更多问题:
如何在 Smalltalk 中显示“转义字符”。
我知道在 C 中,printf("%d * %d = %d\n", j, i, j * i);
看起来不错。
但是在 Smalltalk 中,Transcript show: ('{1} * {2} = {3}cr.' format: {i. j. i * j}).
不行。
我该如何解决?
我建议进行两项更改:
让代码与通用 Stream
一起使用,并将其与 Transcript
一起使用
dumpTableOn: aStream
<your code here>
然后评估
self dumpTableOn: Transcript
用两种方法拆分代码
dumpTableOn: aStream
1 to: 9 do: [:i |
1 to: i do: [:j |
self dump: i times: j on: aStream.
aStream space].
aStream cr]
dump: i times: j on: aStream
aStream
nextPutAll: j asString;
nextPutAll: ' * ';
nextPutAll: i asString;
nextPutAll: ' = ';
nextPutAll: (j * i) asString
这是上述方法的简化版本
dump: i times: j on: aStream
aStream
print: j;
print: ' * ';
print: i;
print: ' = ';
print: j * i
请注意 #print:
不需要我们先将参数转换为 String
。
另请注意,级联不会创建中间体 Strings
,而表达式
j asString, '*', i asString, '=', (j*i) asString
创建 4 个中间字符串(每个 #,
一个)。没什么大不了的,只是我们不会充分利用 Stream
协议,该协议的全部意义在于使客户端无需在其端连接事物。
字符串扩展
Like, printf("%d * %d = %d ", j, i, j * i);
有一些格式化选项,但没有什么比得上 printf (afaik)
'<1p> * <2p> = <3p>' expandMacrosWith: 2 with: 3 with: 2 * 3.
"same as the following:"
'<1p> * <2p> = <3p>' expandMacrosWithArguments: {2. 3. 2 * 3}.
'{1} * {2} = {3}' format: {2. 3. 2 * 3}.
所以你的代码可以重写如下
1 to: 9 do: [ :i |
1 to: i do: [ :j |
Transcript
show: ('{1} * {2} = {3}' format: {j. i. j * i});
show: ' '
].
Transcript show: ' '; cr.
].
更新有关:转义字符
字符串中没有转义字符,唯一的例外是单引号 ('),您 "escape" 将它加倍 ('It''s doubled!'
)
要写新行或制表符,您可以
将其输入字符串
a := 'two
lines'.
(注意 Whosebug 用空格替换了制表符 :/)
加入字符串
b := 'two', String cr, String tab, 'lines'.
告诉写入流添加它
c := String streamContents: [ :stream | stream << 'two'; cr; tab; << 'lines' ].
使用扩展宏
d := 'two<n><t>lines' expandMacros.
a = b = c = d
如果您更喜欢使用类似于 printf
的东西,Squeak 有 expandMacrosWith: 方法系列(浏览 class 字符串)。
你的例子可以写成:
1 to: 9 do: [:i|
1 to: i do: [:j|
Transcript show: ('<1p> * <2p> = <3p> ' expandMacrosWith: j with: i with: j*i)
].
Transcript show: ' '; cr.
].
expandMacros...
的接收器包含尖括号之间的占位符。在Squeak中找不到相关文档,以下摘自Dolphin Smalltalk中等效实现的注释:
Expand the receiver with replacable arguments.
e.g.
'Hello <D><N><1P> <D>' expandMacrosWithArguments: #('World' 1).
'Hello <2?Good:Bad> <1S>' expandMacrosWithArguments: #('World' false)
<nD> expands the nth parameter using it's #displayString
<nP> expands the nth parameter using it's #printString
<nS> expands the nth parameter treating it as a <String>
<N> expands as a newline combination
<T> expands as a TAB
<n?xxxx:yyyy> if the nth parameter is true expands to 'xxxx' else 'expands to yyyy'
我正在使用 Smalltalk 输入 Transcript window 1-9 乘法 table .
这是我的代码:
1 to: 9 do: [:i|
1 to: i do: [:j|
Transcript show: j.
Transcript show: ' * '.
Transcript show: i.
Transcript show: ' = '.
Transcript show: j * i.
Transcript show: ' '.
].
Transcript show: ' '; cr.
].
可以看出,上面的代码虽然工作正常,但看起来远非美观和简洁。
我曾希望写这样的东西:
Transcript show: j '*' i '=' j * i.
不幸的是,他们错了。我记得 C 有一个很好的方法来处理我的那个问题。
喜欢,printf("%d * %d = %d ", j, i, j * i);
在这种情况下,是否有更优雅的方法使 Smalltalk 代码更优雅?
Peter 解决了这个问题。谢谢。
更多问题:
如何在 Smalltalk 中显示“转义字符”。
我知道在 C 中,printf("%d * %d = %d\n", j, i, j * i);
看起来不错。
但是在 Smalltalk 中,Transcript show: ('{1} * {2} = {3}cr.' format: {i. j. i * j}).
不行。
我该如何解决?
我建议进行两项更改:
让代码与通用
一起使用Stream
一起使用,并将其与Transcript
dumpTableOn: aStream <your code here>
然后评估
self dumpTableOn: Transcript
用两种方法拆分代码
dumpTableOn: aStream 1 to: 9 do: [:i | 1 to: i do: [:j | self dump: i times: j on: aStream. aStream space]. aStream cr] dump: i times: j on: aStream aStream nextPutAll: j asString; nextPutAll: ' * '; nextPutAll: i asString; nextPutAll: ' = '; nextPutAll: (j * i) asString
这是上述方法的简化版本
dump: i times: j on: aStream
aStream
print: j;
print: ' * ';
print: i;
print: ' = ';
print: j * i
请注意 #print:
不需要我们先将参数转换为 String
。
另请注意,级联不会创建中间体 Strings
,而表达式
j asString, '*', i asString, '=', (j*i) asString
创建 4 个中间字符串(每个 #,
一个)。没什么大不了的,只是我们不会充分利用 Stream
协议,该协议的全部意义在于使客户端无需在其端连接事物。
字符串扩展
Like, printf("%d * %d = %d ", j, i, j * i);
有一些格式化选项,但没有什么比得上 printf (afaik)
'<1p> * <2p> = <3p>' expandMacrosWith: 2 with: 3 with: 2 * 3.
"same as the following:"
'<1p> * <2p> = <3p>' expandMacrosWithArguments: {2. 3. 2 * 3}.
'{1} * {2} = {3}' format: {2. 3. 2 * 3}.
所以你的代码可以重写如下
1 to: 9 do: [ :i |
1 to: i do: [ :j |
Transcript
show: ('{1} * {2} = {3}' format: {j. i. j * i});
show: ' '
].
Transcript show: ' '; cr.
].
更新有关:转义字符
字符串中没有转义字符,唯一的例外是单引号 ('),您 "escape" 将它加倍 ('It''s doubled!'
)
要写新行或制表符,您可以
将其输入字符串
a := 'two lines'.
(注意 Whosebug 用空格替换了制表符 :/)加入字符串
b := 'two', String cr, String tab, 'lines'.
告诉写入流添加它
c := String streamContents: [ :stream | stream << 'two'; cr; tab; << 'lines' ].
使用扩展宏
d := 'two<n><t>lines' expandMacros.
a = b = c = d
如果您更喜欢使用类似于 printf
的东西,Squeak 有 expandMacrosWith: 方法系列(浏览 class 字符串)。
你的例子可以写成:
1 to: 9 do: [:i|
1 to: i do: [:j|
Transcript show: ('<1p> * <2p> = <3p> ' expandMacrosWith: j with: i with: j*i)
].
Transcript show: ' '; cr.
].
expandMacros...
的接收器包含尖括号之间的占位符。在Squeak中找不到相关文档,以下摘自Dolphin Smalltalk中等效实现的注释:
Expand the receiver with replacable arguments.
e.g.
'Hello <D><N><1P> <D>' expandMacrosWithArguments: #('World' 1).
'Hello <2?Good:Bad> <1S>' expandMacrosWithArguments: #('World' false)
<nD> expands the nth parameter using it's #displayString
<nP> expands the nth parameter using it's #printString
<nS> expands the nth parameter treating it as a <String>
<N> expands as a newline combination
<T> expands as a TAB
<n?xxxx:yyyy> if the nth parameter is true expands to 'xxxx' else 'expands to yyyy'