話題の Big Scripting Languages チートシートの Smalltalk の空欄を埋めてみた [前半]

Smalltalk が普通に入っているのがすばらしいですね。せっかくなので、すこしだけ目立ち気味の空欄を GNU SmalltalkSqueakVisualWorks で項目を分けてからざっと調べて分かる範囲で埋めてみました。スペースの都合と比較のしやすさから、他の言語は Ruby だけ残してありますので、あしからず。GSTer、VWer は、訂正・補足をお願いします。もちろん Squeak使いからのツッコミも歓迎です。


> ruby (1995) GNU Smalltalk (1990) Squeak (1996; 1983, Apple Smalltalk) VisualWorks (1993; 1980, XEROX Smalltalk-80)
versions used 1.8.7; 1.9.1 3.2 4.1 7.7
show version $ ruby --version Smalltalk version

$ gst --version
Smalltalk version SystemUtils version
interpreter $ ruby foo.rb $ gst foo.st none $ visual your.im -filein script.st
repl $ irb $ gst use a Workspace use a Workspace
check syntax $ ruby -c foo.rb none none none
flags for stronger and strongest warnings $ ruby -w foo.pl
$ ruby -W2 foo.pl
none none none
statement separator ; or sometimes newline . (period) or sometimes newline . (period) . (period)
block delimiters {} or do end [ ] [ ] [ ]
assignment a=1 a := 1 a := 1 a := 1
parallel assignment a,b,c = 1,2,3 none none none
swap a,b = b,a | tmp |
tmp := a. a := b. b := tmp
| tmp |
tmp := a. a := b. b := tmp
| tmp |
tmp := a. a := b. b := tmp
compound assignment operators: arithmetic, string, logical, bit += -= *= /= none %= **=
+=
&&= ||= ^=
<<= >>= &= |= ^=
none none none
increment and decrement x not mutated:
x = 1
x.succ
x.pred
none none none
variable declaration assignment; $ prefix denotes global scope Smalltalk at: #GLOBAL put: nil.
assignment; will be local to method
Smalltalk at: #GLOBAL put: nil. for global variable
| local1 local2 | for local variable
Smalltalk at: #GLOBAL put: nil. for global variable
| local1 local2 | for local variable
constant declaration warns if identifier with uppercase first character is reassigned
PI = 3.14
none (Smalltalk associationAt: #GLOBAL) beReadOnlyBinding

MyNameSpace.MyClass defineSharedVariable: #SharedVar
  private: false
  constant: true
  category: 'SharedVar Category'
  initializer: '3 + 4'
end-of-line comment # comment none none none
multiline comment =begin
comment line
another line
=end
"comment line
another line"
"comment line
another line"
"comment line
another line"
null nil nil nil nil
null test v == nil
v.nil?
v = nil
v == nil
v isNil
v = nil
v == nil
v isNil
v = nil
v == nil
v isNil
undefined variable access raises NameError compile error compile error compile error
undefined test ! defined?(v) Smalltalk includesKey: #GLOBAL

MyClass allClassVarNames includes: #ClassVar
Smalltalk includesKey: #GLOBAL

MyClass allClassVarNames includes: #ClassVar

thisContext tempNames includes: #tempVar
Smalltalk includesKey: #GLOBAL

MyClass allClassVarNames includes: #ClassVar

thisContext tempNames includes: #tempVar
arithmetic and logic
> ruby GNU Smalltalk Squeak VisualWorks
true and false true false true false true false true false
falsehoods false nil false false false
logical operators and or not also: && || ! and: or: not always evaluate 2nd operand: & | and: or: not always evaluate 2nd operand: & | and: or: not always evaluate 2nd operand: & |
conditional expression x > 0 ? x : -x x > 0 ifTrue: [x] ifFalse: [0 - x] x > 0 ifTrue: [x] ifFalse: [0 - x]
x positive ifTrue: [x] ifFalse: [x negated]
x > 0 ifTrue: [x] ifFalse: [0 - x]
x positive ifTrue: [x] ifFalse: [x negated]
comparison operators == != > < >= <= = ~= > < >= <= = ~= > < >= <= = ~= > < >= <=
convert from string, to string 7 + "12".to_i
73.9 + ".037".to_f
"value: " + "8".to_s
7 + ‘12’ asNumber
73.9 + '.037' asNumber
'value: ', 8 printString
7 + ‘12’ asNumber
73.9 + '.037' asNumber
'value: ', 8 printString
7 + ‘12’ asNumber
73.9 + '.037' asNumber
'value: ', 8 printString
arithmetic operators + - * x.fdiv(y) / % ** + - * / // \\ raisedTo: + - * / // \\ raisedTo: + - * / // \\ raisedTo: also: **
integer division a / b a // b a // b a // b
float division a.to_f / b or
a.fdiv(b)
a asFloat / b
closure of integers under / is the rationals
a asFloat / b
closure of integers under / is the rationals
a asFloat / b
closure of integers under / is the rationals
arithmetic functions include Math
sqrt exp log sin cos tan asin acos atan atan2
sqrt exp ln sin cos tan arcSin arcCos arcTan arcTan: sqrt exp ln sin cos tan arcSin arcCos arcTan arcTan: sqrt exp ln sin cos tan arcSin arcCos arcTan arcTan:
arithmetic truncation x.abs, x.round, x.ceil, x.floor x abs. x rounded. x ceiling. x floor x abs. x rounded. x ceiling. x floor x abs. x rounded. x ceiling. x floor
min and max [1,2,3].min
[1,2,3].max
none #(1 2 3) min
#(1 2 3) max
#(1 2 3) min
#(1 2 3) max
division by zero integer division raises ZeroDivisionError
float division returns Infinity
raises ZeroDivide raises ZeroDivide raises ZeroDivide
integer overflow becomes arbitrary length integer of type Bignum becomes arbitrary length integer of type LargePositiveInteger becomes arbitrary length integer of type LargePositiveInteger becomes arbitrary length integer of type LargePositiveInteger
float overflow Infinity Inf Infinity raises OverflowSignal
sqrt -2 raises Errno::EDOM returns NaN raises FloatingPointException raises ImaginaryResultSignal
rational numbers require 'rational'
x = Rational(22,7)
x.numerator
x.denominator
x := 22 / 7
x numerator
x denominator
x := 22 / 7
x numerator
x denominator
x := 22 / 7
x numerator
x denominator
complex numbers require 'complex'
z = 1 + 1.414.im
z.real
z.imag
PackageLoader fileInPackage: ‘Complex’.
z := 1 + 1.414 i
z real
z imaginary
z := 1 + 1.414 i
z real
z imaginary
load AT MetaNumerics parcel
z := 1 + 1.414 i
z real
z imaginary
random integer, uniform float, normal float rand(100)
rand
none
rand := Random new
rand between: 1 with: 100
rand next
next
rand := Random new
100 atRandom
rand next
next
rand := Random new
(rand next * 100) asInteger
rand next
none
bit operators << >> & | ^ ~ bitShift: bitAnd: bitOr: bitXor: bitInvert << >> bitAnd: bitOr: bitInvert also: bitShift: bitShift: bitAnd: bitOr: bitXor: bitInvert
strings
> ruby GNU Smalltalk Squeak VisualWroks
character literal none $A $A $A
chr and ord 65.chr
"A".ord
65 asCharacter
$A asciiValue
65 asCharacter
$A asciiValue
65 asCharacter
$A asInteger
string literal 'don\'t say "no"'
"don't say \"no\""
'don''t say "no"' 'don''t say "no"' 'don''t say "no"'
newline in literal yes yes (allows multiline) yes (allows multiline) yes (allows multiline)
here document computer = 'PC'
s = <<EOF
here document
there #{computer}
EOF
none none none
escapes single quoted:
\' \\
double quoted:
\a \b \cx \e \f \n \r \s \t \uhhhh \u{hhhhh} \v \xhh \ooo
none none none
encoding load the I18N package
UTF-8
UTF-8 UTF-8
variable interpolation count = 3
item = "ball"
puts "#{count} #{item}s"
none none, use format: or expandMacros
count := 3
item := 'ball'
'{1} {2}s' format: {count. item}
'<1p> <2s>s' expandMacrosWithArguments: {count. item}
none, use expandMacros
count := 3
item := 'ball'
'<1p> <2s>s' expandMacrosWith: count with: item
length "hello".length
"hello".size
'hello' size 'hello' size 'hello' size
character count '(3*(7+12))'.count('(') '(3*(7+12))' occurrencesOf: $( '(3*(7+12))' occurrencesOf: $( '(3*(7+12))' occurrencesOf: $(
index of substring "foo bar".index("bar") 'foo bar' indexOfSubCollection: 'bar' 'foo bar' findString: 'bar' 'foo bar' findString: 'bar' startingAt: 1
extract substring "foo bar"[4,3] 'foo bar' copyFrom: 5 to: 7 'foo bar' copyFrom: 5 to: 7 'foo bar' copyFrom: 5 to: 7
concatenate "hello, " + "world" 'hello, ', 'world' 'hello, ', 'world' 'hello, ', 'world'
split "foo bar baz".split 'foo bar baz' subStrings 'foo bar baz' subStrings 'foo bar baz' tokensBasedOn: ' '
join ['foo','bar','baz'].join(' ') #('foo' 'bar' 'baz') join: ' ' none, use asStringOn:delimiter:
String streamContents: [:ss | #('foo' 'bar' 'baz') asStringOn: ss delimiter: ' ']
none
scan "hello, hep cat".scan(/\w+/) 'hello, hep cat' allOccurrencesOfRegex: '\w+' none none
pack and unpack f="a5ilfd"
s=["hello",7,7,3.14,3.14].pack(f)
s.unpack(f)
none none none
sprintf "tie: %s %d %f" % ['Spain',13,3.7] none none none
case manipulation "hello".upcase
"HELLO".downcase
"hello".capitalize
'hello' asUppercase
'hello' asLowercase
none
'hello' asUppercase
'hello' asLowercase
'hello' capitalized
'hello' asUppercase
'hello' asLowercase
'hello' capitalized
strip " foo ".strip
" foo".lstrip
"foo ".rstrip
none ' foo ' withBlanksTrimmed
' foo' withoutLeadingBlanks
'foo ' withoutTrailingBlanks
none
pad on right, on left "hello".ljust(10)
"hello".rjust(10)
none 'hello' forceTo: 10 paddingWith: $
'hello' forceTo: 10 paddingStartWith: $
none
character translation "hello".tr('a-z','n-za-m') none none, use translateWith: none
regexp match "1999".match(/^\d{4}$/)
"foo BAR".match(/^[a-z]+/)
"foo BAR".match(/[A-Z]+/)
'1999' =~ '^\d{4}$'
'foo BAR' =~ '^[a-z]+'
'foo BAR' =~ '[A-Z]+'
none none
match, prematch, postmatch s = "A 17 B 12"
while (/\d+/.match(s)) do
 &nbspdiscard = $‘
 &nbspnumber = $&
 &nbsps = $’
 &nbspputs number
end
none, use onOccurrencesOfRegex:do:

s := 'A 17 B 12'.
s onOccurrencesOfRegex: '\d+'
 do: [:each | each match displayNl]
none none
substring matches reg = /(\d{4})-(\d{2})-(\d{2})/
m = reg.match("2010-06-03")
yr,mn,dy = m[1..3]
reg := '(\d{4})-(\d{2})-(\d{2})'.
m := '2010-06-03' =~ reg.
yr := m at: 1.
mn := m at: 2.
dy := m at: 3
none none
single substitution "teh last of teh Mohicans".sub(/teh/,'the') 'teh last of teh Mohicans' replacingRegex: 'teh' with: 'the' none none
global substitution "teh last of teh Mohicans".gsub(/teh/,'the') 'teh last of teh Mohicans' replacingAllRegex: 'teh' with: 'the' none none
containers
> ruby GNU Smalltalk Squeak VisualWorks
array literal nums = [1,2,3,4] nums := #(1 2 3 4) nums := #(1 2 3 4) nums := #(1 2 3 4)
array size nums.size or
nums.length
nums size nums size nums size
array lookup nums[0] nums at: 1 nums at: 1 nums at: 1
array slice nums[1..2] nums copyFrom: 2 to: 3 nums copyFrom: 2 to: 3 nums copyFrom: 2 to: 3
array iteration [1,2,3].each { |i| puts i } nums do: [:o | o displayNl] nums do: [:o | Transcript cr; show: o] nums do: [:o | Transcript show: o; cr]
membership nums.include?(7) nums includes: 7 nums includes: 7 nums includes: 7
intersection [1,2] & [2,3,4] none, use select: #(1 2) intersection: #(2 3 4) none, use select:
union [1,2] | [2,3,4] none, use asSet #(1 2) union: #(2 3 4) none, use asSet
map [1,2,3].map { |o| o*o } #(1 2 3) collect: [:o | o*o] #(1 2 3) collect: [:o | o*o] #(1 2 3) collect: [:o | o*o]
filter [1,2,3].select { |o| o > 1 } #(1 2 3) select: [:o | o > 1] #(1 2 3) select: [:o | o > 1] #(1 2 3) select: [:o | o > 1]
reduce [1,2,3].inject(0) { |m,o| m+o } #(1 2 3) inject: 0 into: [:m :o| m + o]
#(1 2 3) fold: [:m :o | m + o]
#(1 2 3) inject: 0 into: [:m :o| m + o] #(1 2 3) inject: 0 into: [:m :o| m + o]
#(1 2 3) fold: [:m :o | m + o]
universal predicate [1,2,3,4].all? {|i| i.even? } #(1 2 3 4) allSatisfy: [:o | o even] #(1 2 3 4) allSatisfy: [:o | o even] #(1 2 3 4) allSatisfy: [:o | o even]
existential predicate [1,2,3,4].any? {|i| i.even? } #(1 2 3 4) anySatisfy: [:o | o even] #(1 2 3 4) anySatisfy: [:o | o even] #(1 2 3 4) anySatisfy: [:o | o even]
map literal h = { 't' => 1, 'f' => 0 } h := Dictionary new add: 't'->1; add: 'f'->0; yourself h := {'t'->1. 'f'->0} as: Dictionary

h := Dictionary new add: 't'->1; add: 'f'->0; yourself
h := Dictionary new add: 't'->1; add: 'f'->0; yourself
map size h.size or
h.length
h size h size h size
map lookup h['t'] h at: 't' h at: 't' h at: 't'
is map key present h.has_key?('y') h includesKey: 'y' h includesKey: 'y' h includesKey: 'y'
map iteration h.each { |k,v| code} h keysAndValuesDo: [:k :v | code] h keysAndValuesDo: [:k :v | code] h keysAndValuesDo: [:k :v | code]
keys and values of map as array h.keys
h.values
h keys
h values
h keys
h values
h keys
h values
out of bounds behavior nil raises IndexOutOfRange raises error raises error
functions
> ruby GNU Smalltalk Squeak VisualWorks
function declaration def add(a,b); a+b; end add := [:a :b | a+b] add := [:a :b | a+b] add := [:a :b | a+b]
function invocation add(1,2) add value: 1 value: 2
add valueWithArguments: #(1 2)
add valueWithArguments: {1. 2}
add value: 1 value: 2
add valueWithArguments: #(1 2)
add valueWithArguments: {1. 2}
add value: 1 value: 2
add valueWithArguments: #(1 2)
missing argument raises ArgumentError raises WrongArgumentCount raises error raises error
default value def log(x,base=10) none none none
arbitrary number of arguments def add(first, *rest)
 &nbspif rest.empty?
    first
 &nbspelse
    first + add(*rest)
 &nbspend
end
none none none
named parameter definition def f(h) none none none
named parameter invocation f(:eps => 0.01) none none none
pass by reference none none none
return value return arg or last expression evaluated ^ arg or last expression evaluated ^ arg or last expression evaluated ^ arg or last expression evaluated
multiple return values none none none
lambda declaration f = lambda { |x| x * x } f := [:x | x * x] f := [:x | x * x] f := [:x | x * x]
lambda invocation f.call(2) f value: 2 f value: 2 f value: 2
default scope local local local local
nested function definition not allowed not allowed (nested method definition) not allowed (nested method definition) not allowed (nested method definition)
execution control
> ruby GNU Smalltalk Squeak VisualWorks
if if n == 0
 &nbspputs "no hits"
elsif 1 == n
 &nbspputs "1 hit"
else
 &nbspputs "#{n} hits"
end
(n = 0
  ifTrue: ['no hits']
  ifFalse: [n = 1
    ifTrue: ['1 hit']
    ifFalse: [n printString, ' hits']]) displayNl
Transcript cr; show: (n = 0
  ifTrue: ['no hits']
  ifFalse: [n = 1
    ifTrue: ['1 hit']
    ifFalse: [n printString, ' hits']])

or use case-switch like caseOf:otherwise: method

Transcript cr; show: (
  n caseOf: {
    [0] -> ['no hits'].
    [1] -> ['1 hit']}
  otherwise:[n printString, ' hits'])
Transcript show: (n = 0
 ifTrue: ['no hits']
  ifFalse: [n = 1
    ifTrue: ['1 hit']
    ifFalse: [n printString, ' hits']]); cr
while while i < 100
  i += 1
[i < 100] whileTrue: [i := i + 1]
[i >= 100] whileFalse: [i := i + 1]
[i := i + 1. i< 100] whileTrue
[i := i + 1. i >= 100] whileFalse
[i < 100] whileTrue: [i := i + 1]
[i >= 100] whileFalse: [i := i + 1]
[i := i + 1. i< 100] whileTrue
[i := i + 1. i >= 100] whileFalse
[[i < 100] whileTrue: [i := i + 1]
[i >= 100] whileFalse: [i := i + 1]
[i := i + 1. i< 100] whileTrue
[i := i + 1. i >= 100] whileFalse
break/continue/redo break, next, redo none none none
[:break |
  [i := i + 1. i > 100 ifTrue: [break value]] repeat
] valueWithExit
for none none; use to:by:do: method

10 to: 1 by: -1 do: [:i |
  i displayNl
]
none; use to:by:do: method

10 to: 1 by: -1 do: [:i |
  Transcript cr; show: i
]
none; use to:by:do: method

10 to: 1 by: -1 do: [:i |
  Transcript show: i; cr
]
range iteration (1..10).each { |i| puts i } (1 to: 10) do: [:i | i displayNl] (1 to: 10) do: [:i | Transcript cr; show: i] (1 to: 10) do: [:i | Transcript show: i; cr]
statement modifiers
raise exception raise "bad arg" self error: 'bad arg' self error: 'bad arg' self error: 'bad arg'
catch exception begin
  risky
rescue
  puts "risky failed"
end
[risky]
  ifError: ['risky failed' displayNl]

[risky]
  on: Exception
  do: ['risky failed' displayNl]
[risky]
  ifError: [Transcript cr; show: 'risky failed']

[risky]
  on: Exception
  do: [Transcript cr; show: 'risky failed']
[risky]
  on: Exception
  do: [Transcript show: 'risky failed'; cr]
finally/ensure begin
  acquire_resource
  risky
ensure
  release_resource
end
[acquireResource. risky]
  ensure: [eleaseResource]
[acquireResource. risky]
  ensure: [eleaseResource]
[acquireResource. risky]
  ensure: [eleaseResource]
uncaught exception behavior stderr and exit stderr and exit notifier notifier
start thread t = Thread.new { sleep 10 } t := [(Delay forSeconds: 10) wait] fork t := [10 seconds asDelay wait] fork

t := [(Delay forSeconds: 10) wait] fork
t := [10 seconds wait] fork

t := [(Delay forSeconds: 10) wait] fork
wait on thread t.join none, use Semaphore, etc none, use Semaphore, etc none, use Semaphore, etc
environment and i/o
> ruby GNU Smalltalk Squeak VisualWorks
external command system('ls') stream := FileDescriptor popen: 'ls' dir: #read.
contents := stream contents.
stream close.
^contents
none, use OSProcess package ExternalProcess new cshOne: 'ls'
backticks `ls` ?? ?? ??
command line args ARGV.size, ARGV[0], ARGV[1],… Smalltalk arguments size, Smalltalk arguments at: 1 SmalltalkImage current arguments size, SmalltalkImage current argumentAt: 1 ??
print to standard out puts "hi world" 'hi world' displayNl none, use Transcript load Standard IO Streams parcel
OS.Stdout nextPutAll: 'hi world'; cr
standard file handles $stdin $stdout $stderr stdin stdout stderr none OS.Stdin OS.Stdout OS.Stderr
open file f = File.open('/etc/hosts') or
File.open('/etc/hosts') { |f|
f := FileStream open: '/etc/hosts’. or (File path: '/etc/hosts') withReadStreamDo: [:f | f := FileStream fileNamed: ‘/etc/hosts’ or FileStream fileNamed: ‘/etc/hosts’ do: [:f | f := '/etc/hosts' asFilename readStream
open file for writing f = File.open('/tmp/test','w') or
File.open('/tmp/test','w') { |f|
f := FileStream open: 'test.txt' mode: #write or (File path: '/etc/hosts') withWriteStreamDo: [:f | f := FileStream fileNamed: ‘/etc/hosts’ or FileStream fileNamed: ‘/etc/hosts’ do: [:f | f := '/etc/hosts' asFilename writeStream
close file f.close f close f close f close
read line f.gets f nextLine f nextLine f upTo: Character cr
iterate over a file by line f.each do |line| f do: [:char | f do: [:char | f do: [:char |
chomp line.chomp! none none none
read entire file into array or string a = f.lines.to_a
s = f.read
s := f contents s := f contents s := f contents
write to file f.write('hello') f nextPutAll: ‘hello’ f nextPutAll: ‘hello’ f nextPutAll: ‘hello’
flush file f.flush f flush f flush f flush
environment variable ENV['HOME'] Smalltalk getenv: 'HOME' none, use OSProcess package
UnixProcess env at: #HOME
SystemUtils getEnvironmentVariable: 'HOME’
exit exit(0) ObjectMemory quit: 0 none, use
SmalltalkIamge current snapshot: false andQuit: true
ObjectMemory quitWithError: 0
set signal handller Signal.trap("INT", lambda { |signo| puts "exiting…"; exit }) ?? none ??
_______________________ _______________________ _______________________ _______________________


partially copied from http://hyperpolyglot.wikidot.com/scripting then modified by sumim
and also licensed under Creative Commons Attribution-ShareAlike 3.0