a side-by-side reference sheet
grammar and invocation | variables and expressions | arithmetic and logic | strings | regexes | dates and time | arrays | dictionaries | functions | execution control | file handles | files | directories | processes and environment | libraries and namespaces | objects | reflection | java interop
tcl | lua | javascript | groovy | |
---|---|---|---|---|
version used | 8.5 | 5.1 | ECMAScript 5 | 2.2 |
show version | $ tclsh % info tclversion | $ lua -v | $ node --version | $ groovy -v |
grammar and invocation | ||||
tcl | lua | javascript | groovy | |
interpreter | $ tclsh foo.tcl | $ lua foo.lua | $ node foo.js | $ echo 'println "hi!"' > hi.groovy $ groovy hi.groovy |
repl | $ tclsh | $ lua | $ node | $ groovysh |
command line program | none | $ lua -e 'print("hi world!")' | $ node -e 'var sys = require("sys"); sys.puts("hi world!");' | $ groovy -e 'println "hi world!"' |
block delimiters | {} or "" | do end | {} | {} |
statement separator | newline or ; newline not a separator inside {}, "", [] or after backslash: \ | newline or ; newline not separator inside {}, (), or after binary operator. newline can be put in "" or '' if preceded by backslash | ; or newline newline not separator inside (), [], {}, "", '', or after binary operator newline sometimes not separator when following line would not parse as a valid statement | newline or ; newline not a separator inside (), [], triple quote literal, or after binary operator or backslash. |
are expressions statements | no | no | yes | yes |
end-of-line comment | # comment | -- comment | // comment | // comment |
multiple line comment | if (0) { commented out can contain {} if balanced } | --[[ commented out also commented out ]] | /* comment another comment */ | /* comment another comment */ |
variables and expressions | ||||
tcl | lua | javascript | groovy | |
local variable | # set variable inside procedure proc foo {args} { set x 1 … } | local x = 1 | var x = 1; | x = 1 def y = 2 Integer z = 3 |
global variable | # set variable outside procedure set g 1 proc incr_global {} { global g incr g } | -- assign without using local g = 1 function incr_global() g = g + 1 end | // assign without using var g = 1; function incr_global () { g++; } | |
assignment | set x 1 | x = 1 | x = 1; | x = 1 |
parallel assignment | lassign {1 2 3} x y z # 3 is discarded: lassign {1 2 3} x y # z is set to "": lassign {1 2} x y z | x, y, z = 1, 2, 3 -- 3 is discarded: x, y = 1, 2, 3 -- z is set to nil: x, y, z = 1, 2 | none | (x, y, z) = [1, 2, 3] // 3 is discarded: (x, y) = [1, 2, 3] // z is set to null: (x, y, z) = [1, 2] |
swap | lassign "$x $y" y x | x, y = y, x | tmp = x; x = y; y = tmp; | (x, y) = [y, x] |
null | "" | nil | null | null |
null test | v eq "" | v == nil | v === null | v == null |
undefined variable access | error | nil | undefined | raises groovy.lang.MissingPropertyException |
conditional expression | expr $x > 0 ? $x : -$x | none | x > 0 ? x : -x | x > 0 ? x : -x |
arithmetic and logic | ||||
tcl | lua | javascript | groovy | |
true and false | 1 0 | true false | true false | true false |
falsehoods | 0 "false" "no" most strings cause error in boolean context; nonzero numbers are true | false nil | false null undefined "" 0 NaN | false null 0 0.0 "" [] [:] |
logical operators | && || ! | and or not | && || ! | && || ! |
relational expression | if {$x > 3} {…} # outside of conditionals use expr: expr $x > 3 | x > 3 | x > 3 | x > 0 |
relational operators | == != > < >= <= # string comparison: eq ne | == ~= < > >= <= | === !== < > >= <= perform type coercion: == != | == != > < >= <= |
min and max | expr min(1, 2, 3) expr max(1, 2, 3) | math.min(1, 2, 3) math.max(1, 2, 3) math.min(unpack({1 ,2 ,3})) math.max(unpack({1, 2, 3})) | Math.min(1, 2, 3) Math.max(1, 2, 3) Math.min.apply(Math, [1, 2, 3]) Math.max.apply(Math, [1, 2, 3]) | [1, 2, 3].min() [1, 2, 3].max() // binary functions: Math.min(1, 2) Math.max(1, 2) |
arithmetic expression | expr 1 + 3 # expr not needed in conditionals: if {1 + 3} {…} | 1 + 3 | 1 + 3 | 1 + 3 |
arithmetic operators addition, subtraction, multiplication, float division, quotient, modulus | + - * none / % | + - * / none % ^ | + - * / none % | + - * / % |
integer division | expr $x / $y | math.floor(x / y) | Math.floor(x / y) | Math.floor(x / y) |
integer division by zero | error | returns assignable value inf, nan, or -inf depending upon whether dividend is positive, zero, or negative. There are no literals for any of these values. | returns assignable value Infinity, NaN, or -Infinity depending upon whether dividend is positive, zero, or negative. There are literals for Infinity and NaN. | raises java.lang.ArithmeticException |
float division | expr $x * 1.0 / $y | x / y | x / y | x / y |
float division by zero | returns assignable value Inf if dividend is positive and -Inf if negative. Raises error if dividend is zero. There is a literal for Inf. | same behavior as for integers | same behavior as for integers | raises java.lang.ArithmeticException |
power | expr 2 ** 32 expr pow(2, 32) | 2 ^ 32 math.pow(2, 32) | Math.pow(2, 32) | 2 ** 32 |
sqrt | expr sqrt(2) | math.sqrt(2) | Math.sqrt(2) | Math.sqrt(2) |
sqrt -1 | error | nan | NaN | Double.NaN |
transcendental functions | exp log sin cos tan asin acos atan atan2 # how to use math functions: expr exp(2) expr atan2(1, 1) ::tcl::mathfunc::exp 2 ::tcl::mathfunc::atan2 1 1 | math.exp math.log math.sin math.cos math.tan math.asin math.acos math.atan math.atan2 | Math.exp Math.log Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2 | Math.exp Math.log Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2 |
transcendental constants π and e | expr 4 * atan(1) expr exp(1) | math.pi math.exp(1) | Math.PI Math.E | Math.PI Math.E |
float truncation round towards zero, round to nearest integer, round down, round up | expr int(3.1) expr round(3.1) expr floor(3.1) expr ceil(3.1) | none none math.floor(3.1) math.ceil(3.1) | none Math.round(3.1) Math.floor(3.1) Math.ceil(3.1) | (int)3.1 Math.round(3.1) (int)Math.floor(3.1) (int)Math.ceil(3.1) |
absolute value | expr abs(-3) | math.abs(-3) | Math.abs(-3) | Math.abs(-3) |
integer overflow | arbitrary length integers introduced in 8.5 | all numbers are floats | all numbers are floats | becomes type java.math.BigInteger |
float overflow | error | inf | Infinity | Double.POSITIVE_INFINITY |
random number uniform integer, uniform float, normal float | expr int(rand() * 100) expr rand() none | math.random(100) - 1 math.random() none | Math.floor(Math.random() * 100) Math.random() none | rnd = new Random() rnd.nextInt(100) rnd.nextDouble() |
random seed how to set | expr srand(17) | math.randomseed(17) | none | rnd = new Random() rnd.setSeed(17) |
bit operators left shift, right shift, and, inclusive or, exclusive or, complement | << >> & | ^ ~ | none | << >> & | ^ ~ | << >> & | ^ ~ |
strings | ||||
tcl | lua | javascript | groovy | |
string literal | "don't say \"no\"" {don't say "no"} | "don't say \"no\"" 'don\'t say "no"' | "don't say \"no\"" 'don\'t say "no"' | "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, if preceded by backslash | yes | // triple quote literals only: """foo bar""" '''foo bar''' |
character escapes | in double quotes: \a \b \f \n \r \t \v \\ \" \oooo \uhhhh \xhh | single and double quotes: \a \b \f \n \r \t \v \" \' \\ \ddd | single and double quotes: \b \f \n \r \t \v \uhhhh \xhh \" \' \\ | // single and double quotes // including triple quotes: \b \f \n \r \t \\ \" \' \uhhhh \o \oo \ooo // slash quotes: \/ |
variable interpolation | set count 3 set item "ball" "$count ${item}s" | none | none | count = 3 item = "ball" "$count ${item}s" """$count ${item}s""" |
expression interpolation | none | none | none | "1 + 1 = ${1 + 1}" """1 + 1 = ${1 + 1}""" |
string concatenation | set s1 "Hello, " set s2 "World!" set s $s1$s2 | s = "Hello, " .. "World!" | s = "Hello, " + "World!"; | s = "Hello, " + "World!" |
split | split "do re mi" | none | "do re mi".split(" ") | "do re mi".split() |
join | join [list "do" "re" "mi"] " " | table.concat({"do","re","mi"}, " ") | ["do", "re", "mi"].join(" ") | ["do", "re", "mi"].join(" ") |
sprintf | set fmt "lorem %s %d %.2f" format $fmt "ipsum" 13 3.7 | string.format("lorem %s %d %.2f", "ipsum", 13, 3.7) | none | fmt = "lorem %s %d %.2f" String.format(fmt, "ipsum", 13, 3.7) |
case manipulation | string toupper "lorem" string tolower "LOREM" none | string.upper("lorem") string.lower("LOREM") none | "lorem".toUpperCase() "LOREM".toLowerCase() none | "lorem".toUpperCase() "LOREM".toLowerCase() "lorem".capitalize() |
strip | string trim " lorem " string trimleft " lorem" string trimright "lorem " | none | " lorem ".trim() # some browsers: " lorem".trimLeft() "lorem ".trimRight() | " lorem ".trim() |
pad on right, on left, centered | format "%10s" "lorem" format "%-10s" "lorem" | none | none | "lorem".padRight(10) "lorem".padLeft(10) "lorem.center(10) |
string to number | use expr to interpret as numbers: set x "12" expr 7 + $x set y ".037" expr 73.9 + $y | 7 + tonumber("12") 73.9 + tonumber(".037") arithmetic operators attempt numeric conversion of string operands | 7 + parseInt("12", 10) 73.9 + parseFloat(".037") | 7 + Integer.parseInt("12") 73.9 + Double.parseDouble(".037") |
number to string | all values are strings | "value: " .. 8 | "value: " + 8 | "value: " + 8 // explicit conversion: 8.toString() |
length | string length "lorem" | string.len("lorem") | "lorem".length | "lorem".size() "lorem".length() |
index of substring | string first "ipsum" "lorem ipsum" | string.find("lorem ipsum", "ipsum") | "lorem ipsum".indexOf("ipsum") | "lorem ipsum".indexOf("ipsum") |
extract substring | string range "lorem ipsum" 6 10 | string.sub("lorem ipsum", 7, 11) | "lorem ipsum".substr(6, 5) "lorem ipsum".substring(6, 11) | "lorem ipsum".substring(6, 11) |
chr and ord | format %c 65 scan A %c ascii_value | string.char(65) string.byte("A") | String.fromCharCode(65) "A".charCodeAt(0) | (Character)65 (Integer)'A' |
regular expressions | ||||
tcl | lua | javascript | groovy | |
character class abbreviations and anchors | char class abbrevs: . \d \D \s \S \w \W anchors: ^ $ \A \m \M \y \Y \Z | char class abbrevs: . %a %c %d %l %p %s %u %w %x %z anchors: ^ $ | char class abbrevs: . \d \D \s \S \w \W anchors: ^ $ \b \B | char class abbrevs: . \d \D \s \S \w \W anchors: ^ $ \b |
match test | if [regexp -- {1999} $s] { puts "party!" } | if string.match(s, "1999") then print("party!") end | if (s.match(/1999/)) { alert("party!"); } | s = "it is 1999" if (s =~ /1999/) { println("party!") } |
case insensitive match test | regexp -nocase -- {lorem} "Lorem" | none | "Lorem".match(/lorem/i) | "Lorem" =~ /(?i)lorem/ |
modifiers | -all -expanded -indices -inline -line -lineanchor -linestop -nocase | none | g i m | i s |
substitution | set s "do re mi mi mi" regsub -all -- "mi" $s "ma" | s = "do re mi mi mi" s = string.gsub(s, "mi", "ma") | s = "do re mi mi mi"; s.replace(/mi/g, "ma"); | "do re mi mi mi".replaceAll(/mi/, "ma") |
group capture | set s "2009-06-03" set rx {^(\d{4})-(\d{2})-(\d{2})$} regexp -- $rx $s - yr mo dy | s = "2010-06-03" rx = "(%d+)-(%d+)-(%d+)" yr, mo, dy = string.match(s, rx) | rx = /^(\d{4})-(\d{2})-(\d{2})$/; m = rx.exec('2009-06-03'); yr = m[1]; mo = m[2]; dy = m[3]; | s = "2010-06-03" m = s =~ /(\d{4})-(\d{2})-(\d{2})/ yr = m.group(1) mo = m.group(2) dy = m.group(3) |
backreference in regex, in substitution string | regexp -- {(\w+) \1} "do do" set rx {(\w+) (\w+)} regsub -all -- $rx "do re" {\2 \1} | string.match("do do", "(%w+) %1") rx = "(%w+) (%w+)" string.gsub("do re", rx, "%2 %1") | /(w+) \1/.exec("do do") "do re".replace(/(\w+) (\w+)/, '$2 $1') | "do do" =~ /(\w+) \1/ rx = /(\w+) (\w+)/ "do re".replaceAll(rx, '$2 $1') |
dates and time | ||||
tcl | lua | javascript | groovy | |
current date/time | set t [clock seconds] | t = os.time() | var t = new Date(); | t = new Date() |
to unix epoch, from unix epoch | t set t2 1315716177 | t t2 = 1315716177 | Math.round(t.getTime() / 1000) var epoch = 1315716177; var t2 = new Date(epoch * 1000); | Math.round(t.getTime() / 1000) t = new Date(1315716177 * 1000) |
strftime | set fmt "%Y-%m-%d %H:%M:%S" clock format $t -format $fmt | os.date("%Y-%m-%d %H:%M:%S", t) | none | |
strptime | none | none | none | |
parse date w/o format | set t [clock scan "July 7, 1999"] | none | var t = new Date("July 7, 1999"); | |
get date parts | clock format $t -format "%Y" clock format $t -format "%m" clock format $t -format "%d" | none | t.getFullYear() t.getMonth() + 1 t.getDate() # getDay() is day of week | |
get time parts | clock format $t -format "%H" clock format $t -format "%M" clock format $t -format "%S" | none | t.getHours() t.getMinutes() t.getSeconds() | |
build date/time from parts | none | none | var yr = 1999; var mo = 9; var dy = 10; var hr = 23; var mi = 30; var ss = 0; var t = new Date(yr,mo-1,dy,hr,mi,ss); | |
sleep | after 500 | none | none | |
arrays | ||||
tcl | lua | javascript | groovy | |
literal | set a [list 1 2 3 4] set a {1 2 3 4} | a = { 1, 2, 3, 4 } | a = [1, 2, 3, 4] | a = [1, 2, 3, 4] |
size | llength $a | -- not well-defined if array -- contains nil values: # a | a.length | a.size |
lookup | lindex $a 0 | a[1] | a[0] | a[0] |
update | # provide start and end index # of elements to replace: set a [lreplace $a 1 1 "lorem"] | a[1] = "lorem" | a[0] = "lorem" | a[0] = 'lorem' |
out-of-bounds behavior | returns "" | returns nil | returns undefined | returns null |
index of element first and last occurrence | lsearch {6 7 7 8} 7 lindex [lsearch -all {6 7 7 8} 7] end # returns -1 if not found | none; use for and ipairs | [6, 7, 7, 8].indexOf(7) [6, 7, 7, 8].lastIndexOf(7) // returns -1 if not found | [6, 7, 7, 8].indexOf(7) [6, 7, 7, 8].lastIndexOf(7) // returns -1 if not found |
slice | lrange $a 1 2 | none | ["a", "b", "c", "d"].slice(1,3) | // ['b', 'c']: ['a', 'b', 'c', 'd'][1..2] |
slice to end | lrange {"a" "b" "c" "d"} 1 end | none | ["a", "b", "c", "d"].slice(1) | // ['b', 'c', 'd']: ['a', 'b', 'c', 'd'][1..-1] |
concatenate | set a [concat {1 2 3} {4 5 6}] | none | a = [1, 2, 3].concat([4, 5, 6]); | [1, 2, 3] + [4, 5, 6] |
replicate | lrepeat 10 "" | none | none | a = [null] * 10 |
manipulate back | set a {6 7 8} lappend a 9 set i [lindex $a end] set a [lreplace $a end end] | a = {6, 7, 8} table.insert(a, 9) i = table.remove(a) | a = [6, 7, 8]; a.push(9); i = a.pop(); | a = [6, 7, 8] a.push(9) // also: a << 9 i = a.pop() |
manipulate front | set a {6 7 8} set a [concat {5} $a] set a [lassign $a i] | a = {6, 7, 8} table.insert(a, 1, 5) i = table.remove(a, 1) | a = [6, 7, 8]; a.unshift(5); i = a.shift(); | a = [6, 7, 8] a.add(0, 5) i = a.remove(0) |
iterate over elements | foreach i $a { puts $i } | for k,v in ipairs(a) do print(v) end | var len = a.length; for (var i = 0; i < len; i++ ) { alert(a[i]); } | for (i in [1, 2, 3, 4]) { println i } |
reverse | set a {1 2 3} set a [lreverse $a] | none | var a = [1, 2, 3]; a.reverse(); | a = [1, 2, 3] a.reverse() |
sort | set a {3 1 4 2} set a [lsort $a] | a = {3, 1, 4, 2} table.sort(a) | var a = [3, 1, 4, 2]; a.sort(); | a = [3, 1, 4, 2] a.sort() |
dedupe | lsort -unique {1 2 2 3} | none | none | a = [1, 2, 2, 3] // modifies array in place: a.unique() |
membership | expr {7 in $a} expr {7 ni $a} | none | none | [1, 2, 3].contains(7) ![1, 2, 3].contains(7) |
intersection | package require struct::set ::struct::set intersect {1 2} {2 3} | none | none | [1, 2].intersect([2, 3]) |
union | package require struct::set ::struct::set union {1 2} {2 3 4} | none | none | ([1, 2] + [2, 3, 4]).unique() |
relative complement | package require struct::set ::struct::set difference {1 2 3} {2} | none | none | [1 2 3] - [2] |
map | package require struct::list proc sqr {x} {return [expr $x * $x]} ::struct::list map {1 2 3} sqr | none | // callback gets 3 args: // value, index, array a.map(function(x) { return x * x }) | [1, 2, 3].collect() { n -> n * n } |
filter | package require struct::list proc gt1 {x} {return [expr $x > 1]} ::struct::list filter {1 2 3} gt1 | none | a.filter(function(x) { return x > 1 }) | [1, 2, 3].findAll() { x -> x > 2 } |
reduce | package require struct::list ::struct::list fold {1 2 3} 0 ::tcl::mathop::+ | none | a.reduce(function(m, o) { return m + o; }, 0) | [1, 2, 3].inject(0) { x, y -> x + y } |
universal and existential tests | none | none | var a = [1, 2, 3, 4]; var even = function(x) { return x % 2 == 0; }; a.every(even) a.some(even) | none |
shuffle | none | none | none | a = [1, 2, 3, 4] // no return value: Collections.shuffle(a) |
zip | none | none | none | [[1,2,3], ['a', 'b', 'c']].transpose() |
dictionaries | ||||
tcl | lua | javascript | groovy | |
literal | set d [dict create t 1 f 0] | d = { t=1, f=0 } | d = { "t":1, "f":0 }; keys do not need to be quoted if they are a legal JavaScript variable name and not a reserved word | d = ["t": 1, "f": 0] |
size | dict size $d | size = 0 for k, v in pairs(d) do size = size + 1 end | var size = 0; for (var k in d) { if (d.hasOwnProperty(k)) size++; } | d.size() |
lookup | dict get $d t | d.t d["t"] | d.t d["t"] | d["t"] |
update | dict set d t 2 | d["t"] = 2 d.t = 2 | d["t"] = 2; d.t = 2; | d["t"] = 2 |
out of bounds behavior | error | returns nil | returns undefined | returns null |
is key present | dict exists $d t | d["t"] ~= nil | d.hasOwnProperty("t"); | d.containsKey("t") |
delete | dict unset d t | d.t = nil d["t"] = nil | delete d["t"]; delete d.t; | |
iteration | foreach {k v} $d { code } | for k,v in pairs(d) do use k or v end | for (var k in d) { use k or d[k] } | |
functions | ||||
tcl | lua | javascript | groovy | |
function declaration | proc add { x y } { expr $x + $y } | function add(x, y) return x + y end | function add(x, y) { return x+y; } | def (x, y) { x + y } |
function invocation | add 1 2 | add(1, 2) | add(1, 2) | add(1, 2) // parens are optional: add 1, 2 |
missing argument value | error | nil | undefined | raises groovy.lang.MissingMethodException |
extra arguments | error | ignored | available in arguments | raises groovy.lang.MissingMethodException |
default value | proc log {x {base 10 }} { body } | none | none | |
variable number of arguments | last arg contains list of remaining values | declare function with ellipsis: function foo(...) local arg = {...} | args in arguments[0], arguments[1], … with number of args in arguments.length | |
return value | return arg or empty string | return arg or nil | return arg or undefined. If invoked with new and return value not an object, returns this | return arg or last expression evaluated |
multiple return values | none | function roots(x) r = math.sqrt(x) return r, -r end r1,r2 = roots(4) | none | none |
lambda declaration | set sqr {{x} {return [expr $x*$x]}} | sqr = function(x) return x*x end | sqr = function(x) { return x*x; } | sqr = { x -> Math.sqrt x } |
lambda invocation | apply $sqr 2 | sqr(2) | sqr(2) | sqr(2) |
default scope | local | global unless declared with local | global unless declared with var | |
nested function visibility | not visible outside containing function | visible outside containing function | not visible outside containing function | |
execution control | ||||
tcl | lua | javascript | groovy | |
if | if { 0 == $n } { puts "no hits" } elseif { 1 == $n } { puts "1 hit" } else { puts "$n hits" } | if n == 0 then print("no hits") elseif n == 1 then print("one hit") else print(n .. " hits") end | if (0 == n) { alert("no hits"); } else if (1 == n) { alert("1 hit"); } else { alert(n + " hits"); } | if (n == 0) { println("no hits") } else if (n == 1) { println("one hit") } else { println(n + " hits") } |
while | while { $i < 100 } { incr i } | while i < 100 do i = i + 1 end | while ( i < 100 ) { i += 1; } | while (i < 100) { i += 1 } |
break and continue | break continue | break none | break continue | break continue |
for | for {set i 0} {$i < 10} {incr i} { puts $i } | for i = 0, 9 do print(i) end | for (var i=0; i<10; i++) { alert(i); } | for (i = 0; i < 10; i++) { println i } |
raise exception | error "bad arg" | error "bad arg" | throw "bad arg"; | throw new Exception("bad arg") |
catch exception | catch risky retval if { retval != 0 } { puts "risky failed" } | if not pcall(risky) then print "risky failed" end | try { risky(); } catch (e) { alert("risky failed"); } | |
finally/ensure | none | none | acquire_resource(); try { risky(); } finally { release_resource(); } | |
uncaught exception behavior | stderr and exit | stderr and exit | error to console; script terminates. Other scripts in page will execute | |
generator | to be added to Tcl 8.6 | crt = coroutine.create( function (n) while (true) do coroutine.yield(n % 2) n = n + 1 end end ) status, retval = coroutine.resume(crt, 1) if status then print("parity: " .. retval) else print("couldn't resume crt") end _, retval = coroutine.resume(crt) print("parity: " .. retval) | none | |
file handles | ||||
tcl | lua | javascript | groovy | |
standard file handles | stdin stdout stderr | io.stdin io.stdout io.stderr | System.in System.out System.err | |
read line from stdin | gets stdin line | line = io.stdin:read() | js: var line = readline(); | |
write line to stdout | puts "Hello, World!" | print "Hello, World!" | var sys = require('sys'); sys.puts("Hello, World!"); | print("Hello, World!\n") println("Hello, World!") System.out.print("Hello, World!\n") System.out.println("Hello, World!") |
open file | set f [open "/tmp/foo"] | f = io.open("/tmp/foo") | var fs = require('fs'); f = fs.openSync("/tmp/foo", "r"); | |
open file for writing | set f [open "/tmp/foo" "w"] | f = io.open("/tmp/foo", "w") | var fs = require('fs'); f = fs.openSync("/tmp/foo", "w"); | |
close file | close $f | f:close() | fs.closeSync(f); | |
read line | gets $f | f:read() | ||
iterate over a file by line | while { [gets $f s] >= 0 } { use s } | for s in f:lines() do use s end | var fs = require('fs'); var file = fs.readFileSync("/etc/hosts").toString(); file.split("\n").forEach(function (s) { use s }); | |
chomp | string trimright $line "\r\n" | none, read() and lines() remove trailing newlines | ||
read file | read $f | f:read("*a") | var fs = require('fs'); fs.readFileSync("/tmp/foo", "utf8"); | |
write to file | puts -nonewline $f "lorem ipsum" | f:write("lorem ipsum") | fs.writeSync(f, "lorem ipsum"); | |
flush file handle | flush $f | f:flush() | none | |
files | ||||
tcl | lua | node.js | groovy | |
file exists test, file regular test | file exists "/etc/hosts" file isfile "/etc/hosts" | none | var path = require('path'); path.existsSync("/etc/hosts"); | f = new File('/etc/hosts') f.exists() f.isFile() |
file size | f = new File('/etc/hosts') f.length() | |||
is file readable, writable, executable | f = new File('etc/hosts') f.canRead() f.canWrite() f.canExecute() | |||
copy file, remove file, rename file | file copy "/tmp/foo" "/tmp/bar" file delete "/tmp/foo" file rename "/tmp/bar" "/tmp/foo" | none | var fs = require('fs'); fs.unlink("/tmp/foo"); fs.rename("/tmp/bar", "/tmp/foo"); | |
set file permissions | set s "/tmp/foo" file attributes $s -permissions 0755 | none | var fs = require('fs'); fs.chmod("/tmp/foo", 0755); | |
temporary file | set tmp [::fileutil::tempfile foo] set f [open $tmp "w"] puts $f "lorem ipsum" close $f puts "tmp file: $tmp" | f = io.tmpfile() f:write("lorem ipsum\n") f:close() | ||
directories | ||||
tcl | lua | node.js | groovy | |
build pathname | file join "/etc" "hosts" | var path = require('path'); path.join("/etc", "hosts"); | ||
dirname and basename | file dirname "/etc/hosts" file tail "/etc/hosts" | var path = require('path'); path.dirname("/etc/hosts"); path.basename("/etc/hosts"); | ||
iterate over directory by file | var fs = require('fs'); var sys = require('sys'); var a = fs.readdirSync("/etc"); for (var i=0; i<a.length; i++) { sys.puts(a[i]); } | |||
make directory | file mkdir "/tmp/foo/bar" | var fs = require('fs'); fs.mkdirSync("/tmp/foo", 0755); fs.mkdirSync("/tmp/foo/bar", 0755); | ||
remove empty directory | file delete "/tmp/foodir" | var fs = require('fs'); fs.rmdirSync("/tmp/foo/bar"); | ||
remove directory and contents | file delete -force "/tmp/foodir" | |||
directory test | file isdirectory "/tmp" | |||
processes and environment | ||||
tcl | lua | node.js | groovy | |
command line args | [lindex $argv 0] [lindex $argv 1] … | # arg arg[0] arg[1] … | process.argv.length process.argv[0] process.argv[1] … | args.size() args[0] args[1] … |
environment variable | $env(HOME) | os.getenv("HOME") | System.getenv("HOME") | |
exit | exit 0 | os.exit(0) | process.exit(0) | System.exit(0) |
external command | exec ls | os.execute("ls") | var exec = require('child_process').exec; var child = exec('ls'); | |
backticks | set f [ open |ls ] read f | f = io.popen("ls") s = f:read("*a") | var exec = require('child_process').exec; var f = function(err, fout, ferr) { output in fout }; var child = exec('ls', f); | |
libraries and namespaces | ||||
tcl | lua | javascript | groovy | |
library | $ cat foo.tcl proc add {x y} {expr $x + $y} | $ cat foo.lua function add(x, y) return x+y end | $ cat foo.js function add(x,y) { return x+y; } | |
import library | source foo.tcl add 3 7 | require 'foo' add(3,7) | <script src="foo.js"/> <script> alert(add(3,7)); </script> | |
library path | none | package.path | node.js, not available in repl: require.paths | |
library path environment variable | TCLLIBPATH | LUA_PATH | none | |
namespace declaration | namespace | module | ||
namespace separator | :: | . | ||
list installed packaged, install a package | $ npm ls $ npm install tmp | |||
objects | ||||
tcl | lua | javascript | groovy | |
define class | class Int { public int value Int (int n) { value = n } } | |||
create object | o = new Int(3) | |||
create blank object | o = {} | var o = new Object(); or var o = {}; | ||
set attribute | o.score = 21 | o.score = 21; | o.value = 4 | |
get attribute | if o.score == 21 then print("Blackjack!") end | if (o.score == 21) { alert("Blackjack!"); } | o.value | |
define method | function o.doubleScore(self) return 2 * self.score end | o.doubleScore = function() { return this.score * 2; }; | ||
invoke method | print("Answer: " .. o:doubleScore()) | alert("Answer: " + o.doubleScore()); | ||
clone object | var o2 = Object.create(o); | |||
object literal | o = { score=21, doubleScore=function(self) return 2*self.score end } | var o = { score: 21, doubleScore: function() { return this.score * 2; } }; | ||
reflection | ||||
tcl | lua | javascript | groovy | |
inspect type | type(o) | typeof o | o.class o.getClass() | |
has method? | typeof o.foo == 'function' | |||
message passing | o["foo"](1,1) | |||
eval | assert(loadstring("x = 1+1"))() | x = eval("1 + 1"); | ||
inspect methods | "lorem".metaClass.methods | |||
inspect attributes | ||||
java interoperation | ||||
tcl | lua | javascript | groovy | |
__________________________________________ | __________________________________________ | __________________________________________ | __________________________________________ |
The version used for verifying the examples in this cheat sheet.
javascript:
In the JavaScript standard the language is called ECMAScript. Four versions of the standard have been adopted:
ecmascript version | date |
---|---|
1 | June 1997 |
2 | June 1998 |
3 | December 1999 |
5 | December 2009 |
Here is a summary of ECMAScript 5 compliance for recent browsers:
browser | compliance |
---|---|
Chrome 7-12 | all but "use strict" |
Chrome 13+ | all |
Firefox 4+ | all |
IE 9 | all but "use strict" |
IE 10 | all |
Safari 5.1 | all but Function.prototype.bind and zero-width char in identifiers |
Safari 6 | all |
How to get the version.
The customary name of the interpreter and how to invoke it.
unix:
On Unix, scripts are executing by passing the file containing the script to the interpreter as an argument:
bash ~/configure.sh
If the executable bit is set, the file can be run directly:
~/configure.sh
To determine the name of the interpreter that will process the script, Unix will look for the presence of a shebang (#!) at the start of the file. If the pathname to a command follows the shebang, it will be used to interpret the script. If no shebang is present, the script will be interpreted with sh, which is bash on modern Unix systems.
Arguments that follow the command will be passed to interpreter as command line arguments.
If it is undesirable to specify the pathname of the interpreter, the env command can be used to search the PATH directories:
#!/usr/bin/env lua
javascript:
To use a browser to execute JavaScript code, put the code inside a <script> tag in an HTML page and open the page with the browser.
groovy:
Groovy does not in general have # style comments, but one can be used on the first line to create a shebang script:
#!/usr/bin/env groovyprintln "hello world!"
The customary name of the repl.
javascript:
You can use the JavaScript console as a repl. Here are the keystrokes to launch the console:
chrome | firefox | safari | ||
---|---|---|---|---|
mac | win | mac | win | mac |
J | Ctrl+Shift+J | Fn F12 | Ctrl+Shift+K | C |
How to pass in a program to the interpreter on the command line.
How blocks are delimited.
tcl:
The block delimiters {} and "" are the same as the string delimiters. Double quotes "" cause variable interpolation and as a result they are not often used to delimit blocks.
The following three lines of code behave the same:
if {true} {puts "true"}if "true" "puts \"true\""if "true" "puts {true}"
lua:
The function and if keywords open blocks which are terminated by end keywords. The repeat keyword opens a block which is terminated by until.
How the parser determines the end of a statement.
Whether an expression can be used where a statement is expected.
tcl:
Code fragments such as
1 + 1
or
[expr 1 + 1]
result in invalid command name errors when used as statements.
The following is a valid statement:
expr 1 + 1
The above cannot be used as an argument to a command without putting it inside square brackets, however.
Since the constructs which can be used as statements and the constructs which can be used in the positions where expressions are normally used are disjoint, we claim that expressions are not statements in Tcl.
How to make the remainder of the line a comment.
How to comment out multiple lines.
tcl:
The method described requires that there not be an unmatched right curly bracket in the comment.
lua:
The double bracket notation [[ ]] is the syntax for a multiline string literal.
How to declare a local variable.
How to declare and access a global variable.
How to assign a value to a variable.
Whether parallel assignment is supported, and if so how to do it.
How to swap the values in two variables.
The null literal.
How to test if a value is null.
tcl
Tcl has has no null value.
javascript:
null == undefined is true. The triple equality operator === is thus necessary to test if a variable is null.
What happens when the value in an undefined variable is accessed.
tcl:
The following test can be used to determine if a variable is defined:
expr ![info exists v]
lua:
There is no distinction between a variable being defined and a variable having a nil value. Assigning nil to a variable frees it.
javascript:
undefined == null is true. The triple equality operator === is necessary to test if a variable is undefined.
How to write a conditional expression.
lua:
notes on Lua and the ternary operator
The literals for true and false.
Values which are false in conditional expressions.
tcl:
0 is false and all other numeric values are true. For non-numeric strings, "no" and "false" are false, and "yes" and "true" are true. The comparison is case insensitive. All other non-numeric strings raise an error when evaluated in a boolean context.
Logical and, or, and not.
How to write a relational expression.
tcl
To evaluate a relational expression outside of the the conditional of an if statement, the expr command can be used.
Use square brackets to make an expression an argument of a command:
puts [expr $x>1]
The available relational operators.
tcl:
The eq and ne operators always perform comparisons on their operators as strings. If the arguments are numeric, they are converted to a standard floating point representation.
% expr {"0" eq "00"}0% expr {"0" == "00"}1
The == and != operators try to convert their arguments to a numeric form for the purpose of comparison. String comparison is used when no numeric conversion is possible:
% expr {"lorem" == "ipsum"}0
The relational operators can be invoked as commands in the following manner:
% ::tcl::mathop::== 1 11% ::tcl::mathop::!= 1 10% ::tcl::mathop::> 1 1%::tcl::mathop::< 1 10% ::tcl::mathop::>= 1 11% ::tcl::mathop::<= 1 11% ::tcl::mathop::eq "lorem" "ipsum"0%::tcl::mathop::ne "lorem" "ipsum"1
How to find the min and max value in mix of values or variables.
How to evaluate an arithmetic expression.
tcl:
Arithmetic expressions are normally evaluated with the expr command. However, the conditional argument of an if statement is always evaluated as an expression.
The binary arithmetic operators.
The operators for addition, subtraction, multiplication, float division, integer division, modulus, and exponentiation. Some languages provide a function pow instead of an operator for exponentiation.
tcl:
Arithmetic operators are normally used as arguments to expr, but commands also exist for each of them:
::tcl::mathop::+::tcl::mathop::-::tcl::mathop::*::tcl::mathop::/::tcl::mathop::**::tcl::mathop::%
How to perform integer division.
lua:
All Lua numbers are floating point.
What happens when a float is divided by zero.
lua
As already noted there are no literals for inf and nan. Once could assign the correct values
to variables with the following code
inf = 1 / 0nan = 0 / 0
inf can be compared to itself, but nan cannot. In other words:
# this prints 'true'=(1 / 0) == (1 / 0)# this prints 'false'=(0 / 0) == (0 / 0)
How to perform floating point division, even if the operands might be integers.
The result of dividing a float by zero.
How to compute exponentiation.
The examples calculate 2 to the 32 which is the number of distinct values that can be stored in 32 bits.
How to get the square root of a number.
The result of taking the square root of -1.
Functions for computing the natural exponent, natural logarithm, sine, cosine, tangent, arcsine, arccosine, arctangent, and atan2.
The trigonometric functions are all in radians. atan2 takes two arguments which are the x and y co-ordinates of a vector in the Cartesian plane. It returns
the angle to the positive x-axis made by the vector.
Approximate values for π and e.
Ways to convert a float to a nearby integer: towards zero; to the nearest integer; towards positive infinity; towards negative infinity.
How to get the absolute value of a number.
What happens when an operation yields an integer larger than the largest representable value.
What happens when an operation yields a float larger than the largest representable value.
The examples show how to generate a uniform random integer in the range from 0 to 99, inclusive; how to generate a uniform float in the range 0.0 to 1.0; how to generate a float from a standard normal distribution
How to set the seed for the random number generator.
Setting the seed to a fixed number can be used for repeatable results.
The available bit operators.
The syntax for a string literal.
Are newlines permitted in a string literal?
lua:
One can avoid backslashes by using the double bracket string notation. The following are equivalent:
s = "onetwothree"s = [[onetwothree]]
Backslash escape sequences that can be used in a string literal.
The syntax for interpolating variables into a string literal.
Interpolating the result of evaluating an expression in a string literal.
The string concatenation operator.
tcl:
split takes an optional 2nd argument which is a string containing the characters to split on. split can only split on characters, not strings or regular expressions. For each pair of adjacent splitting characters in the input string, there will be an empty string in the result list.
lua:
How to concatenate the elements of an array into a string with a separator.
How to create a string using a printf style format.
How to pad a string to a given length on the right; how to pad on the left; how to center a string inside a larger string of a given length.
groovy
Provide a second argument to set the pad character:
"lorem".padRight(10, '_')"lorem".padLeft(10, '_')"lorem.center(10, '_')
How to convert a string to a number.
tcl:
All values are strings. The expr function will concatenate the arguments together and then evaluate the string as a numerical expression. If all the numbers are integers, the expression is computed using integer arithmetic. Otherwise floating point arithmetic is used. The variables can contain compound arithmetic expressions; the following script outputs 10:
set a "7+3"puts [expr $a]
lua:
Arithmetic operators will attempt to convert strings to numbers; if the string contains non-numeric data an error results. Note that relational operators do not perform conversion. Thus the following expression is false:
0 == '0'
javascript:
Numbers can be explicitly converted to strings with toString(). Numeric literals must be put inside parens to invoke the toString() method.
(8).toString()x = 7x.toString()
How to convert a number to a string.
lua:
print and the .. operator will convert all types to strings.
javascript:
The plus operator + performs concatenation on strings. If either operand is a string, then the other operand will be converted to a string.
100 == "100"
Numbers can be explicitly converted to strings with toString(). Numeric literals must be put inside parens to invoke the toString() method.
(8).toString()x = 7x.toString()
How to get the number of characters in a string.
How to get the index of the leftmost occurrence of a substring.
How to extract a substring.
converting characters to ASCII codes and back
The supported character class abbreviations and anchors
abbrev | description |
---|---|
. | any character; doesn't match newline when -linestop in effect |
^ | beginning of string; beginning of line when -lineanchor in effect |
$ | end of string; end of line when -lineanchor in effect |
\A | beginning of string |
%a | letter |
\b, \y | word boundary |
\B, \Y | not a word boundary |
%c | control character |
\d, %d | digit [0-9] |
\D | not a digit [^0-9] |
%l | lowercase letter |
\m | beginning of a word |
\M | end of a word |
%p | punctuation character |
\s | white space |
\S | not white space |
%u | uppercase letter |
\w, %w | alphanumeric character. \w also matches underscore |
\W | not a word character |
\Z | end of string |
%z | the null character (ASCII zero) |
How to test whether a regular expression matches a string.
groovy
The =~ operator succeeds if the regex matches part of the string. The ==~ succeeds only if the regular expression matches the entire string:
s = "it's 1999"// true:s =~ /1999/// false:s ==~ /1999/
How to test whether a regular expression matches a string, ignoring case.
Available flags for modifying regular expression behavior.
tcl:
modifier | description |
---|---|
-all | causes regexp to return number of matches in string; causes regsub to replace all occurrences of match |
-expanded | ignore whitespace in patten |
-indices | modifies group capture: returns start and end indices of the substring instead of the substring itself |
-inline | return the total match and each of the group captures as a list. Normally the number of matches is returned |
-line | same as using -lineanchor and -linestop |
-lineanchor | causes ^ and $ to match the beginning and ending of lines (\A and \Z still match beginning and ending of string) |
-linestop | causes . to not matcch a newline |
-nocase | makes matching case insensitive |
javascript:
modifier | description |
---|---|
g | when used with match, causes all occurrences of pattern in string to be return in an array; when used with replace causes all occurrences to be replaced |
i | makes matching case insensitive |
m | causes ^ and $ to match beginning and ending of lines instead of the whole string |
How to replace all occurrences of a pattern in a string with a substitution.
tcl:
To replace only the first occurrence of the pattern, omit the -all flag:
set s "do re mi mi mi"regsub "mi" $s "ma"
lua:
To specify the maximum number of pattern occurrences to be replaced, provide a fourth argument:
s = "do re mi mi mi"s = string.gsub(s, "mi", "ma", 1)
javascript:
If the g modifier is not used, only the first occurrence of the pattern will be replaced.
s = "do re mi mi mi";s.replace(/mi/, "ma");
How to get the substrings which matched a parenthesized portion of a regular expression.
How to use backreferences in a regex; how to use backreferences in the replacement string of substitution.
How to get the current time.
How to convert a date/time object to the Unix epoch; how to convert a date/time object from the Unix epoch.
The Unix epoch is the number of seconds since January 1, 1970 UTC. In the case of Tcl and Lua, the native date/time object is the Unix epoch, so no conversion is needed.
How to use a strftime style format string to convert a date/time object to a string representation.
strftime is from the C standard library. The Unix date command uses the same style of format.
How to parse a string into a date/time object using a strftime style format string. strptime is from the C standard library.
How to parse a string into a date/time object without using a format string.
How to get the year as a four digit integer; how to get the month as an integer from 1 to 12; how to get the day of the month as an integer from 1 to 31.
How to get the hour as an integer from 0 to 23; how to get the minute as an integer from 0 to 59; how to get the second as an integer from 0 to 59.
How to assemble a date/time object from the 4 digit year, month (1-12), day (1-31), hour (0-23), minute (0-59), and second (0-59).
How to sleep for half a second.
The names given by the languages for their basic container types:
tcl | lua | javascript | groovy | |
---|---|---|---|---|
array | list | table | Array | java.util.ArrayList |
dictionary | array, dict | table | Object | java.util.LinkedHashMap |
tcl:
Tcl arrays are associative arrays. The dict type is new in Tcl 8.5. See the documentation for array and dict.
lua:
Note that Lua uses the same data structure for arrays and dictionaries.
Array literal syntax.
How to get the number of elements in an array.
lua:
The # operator returns the index of a non-nil value in the array that is followed by a nil value. Unfortunately different Lua implementations behave differently when there are multiple such indices. In particular there is no guarantee that the index will be the index of the last non-nil value in the array.
# a returns the number of times that a for loop used with ipairs will execute.
How to access a value in an array by index.
tcl:
Does not support negative indices. To change the 2nd element in the list a to 8, use
lset a 1 8
lset will not increase the size of the list if the index is out of bounds. For more list manipulation commands see http://www.tcl.tk/man/tcl/tutorial/Tcl15.html.
lua:
Lua arrays are indexed from one.
How to change the value stored in an array at given index.
What happens when a lookup is performed on an out-of-bounds index.
How to get the first or last index containing a value.
How to slice a subarray from an array.
How to slice an array to the end
How to concatenate two arrays.
How to create an array consisting of n copies of a value.
How to push or pop elements from the back an array. The return value of the pop command is the value of the item which is removed.
With these commands an array can be used as a stack.
How to shift or unshift elements to the front of an array. The return value of the shift command is the value of the item which is removed.
With these commands an array can be used as a stack. When combined with the commands from the previous section the array can be used as a queue.
How to iterate through the elements of an array.
How to reverse the order of the elements in an array.
How to sort an array.
How to remove extra occurrences of elements from an array.
dedupe
An O(n2) solution to deduping a JavaScript array:
[1, 2, 2, 3].filter(function (v, i, a) { return a.indexOf (v) == i })
How to test whether a value is an element of an array; how to test whether a value is not an element of an array.
How to compute an intersection.
How to compute the union of two arrays.
How to find the elements of an array that are not in another array.
How to apply a function to the elements of an array.
None of the examples modify the source array.
lua:
javascript:
Array.map() passes three values to the callback function on each iteration: the value in the array, the index of the value in the array, and the entire array.
How to select the elements of an array for which a predicate is true.
None of the examples modify the source array.
lua:
How to reduce an array using a binary operation and an initial value.
None of the examples modify the source array.
lua:
How to test whether all elements in an array satisfy a predicate; how to test whether at least one element in an array satisfies a predicate.
How to shuffle an array.
How to interleave arrays. In the case of two arrays the result is an array of pairs or an associative list.
tcl:
The dict type was introduced in Tcl 8.5.
In earlier versions of Tcl associative arrays were used when a dictionary type was needed, and they remain an alternative in Tcl 8.5. Associative arrays are stored in variables as strings. The array command is used to treat the string as an associative array:
array set d [list "t" 1 "f" 0]array size d$d(t)array set d [list "t" 2]info exists d(t)array unset d "t"foreach {k v} [array get d] { puts k puts v}
The syntax for a dictionary literal.
How to get the number of entries in a dictionary.
How to look up the value associated with a key.
javascript:
JavaScript objects support both o.k and o['k'] style attribute access, but in the former case k must be a valid JavaScript identifier.
How to set or update the value associated with a key.
What happens when a lookup is performed for a key the dictionary does not have.
How to find out whether a value is associated with a key.
How to remove a key/value pair from a dictionary.
How to iterate through all the key/value pairs of a dictionary.
Python has both functions and methods. Ruby only has methods: functions defined at the top level are in fact methods on a special main object. Perl subroutines can be invoked with a function syntax or a method syntax.
How to declare a function.
How to invoke a function.
Value of an argument variable if a function is invoked with fewer arguments than are declared.
If a function is invoked with more arguments than are declared, how the function can access them.
How to declare a default value for an argument.
How to write a function which accepts a variable number of argument.
lua:
In version 5.1 and earlier the global variable arg was set automatically. In version 5.2 one must explicitly assign to a local array.
It is possible to get the number of arguments that were provided without assigning to a local array:
function foo(...) print('passed ' .. select('#', ...) .. ' arguments')end
How the return value of a function is determined.
lua:
If a function returns multiple values, the first value can be selected by placing the invocation inside parens:
function roots(x) return math.sqrt(x), -math.sqrt(x)end(roots(4))
How to define a lambda function.
How to invoke a lambda function.
What scope do variables declared inside a function have by default.
tcl:
Tcl variables inside functions have local scope.
Whether nested functions are visible outside of the function in which they are defined.
The if statement.
tcl:
Tcl also has a switch:
switch $a 0 { puts "no" } 1 { puts "yes" } 2 { puts "maybe" } default { puts "error" }
How to create a while loop.
break exits a for or while loop immediately. continue goes to the next iteration of the loop.
How to create a C-style for loop.
lua:
Provide a third argument to set the step size to something other than the default of one:
for i = 0, 90, 10 do print(i)end
How to raise an exception.
How to handle an exception.
Clauses that are guaranteed to be executed even if an exception is thrown or caught.
System behavior if an exception goes uncaught. Most interpreters print the exception message to stderr and exit with a nonzero status.
tcl:
A tcl process can have multiple interpreters and multiple threads. However, each interpreter is limited to a single thread.
How to create and use a generator.
tcl:
To prevent puts from appending a newline to the output, use
puts -nonewline "hello"
How to read a line from standard input.
Constands for the standard file handles.
How to create a file handle for reading.
How to create a file handle for writing.
How to close a file handle.
Remove a newline, carriage return, or carriage return newline pair from the end of a line if there is one.
javascript:
Browser-embedded JavaScript cannot interact with the browser's operating system. All examples in this section assume the JavaScript code is being executed by node.js.
How to access the command line arguments.
How to access an environment variable.
How to terminate the process and set the status code.
How to register a signal handler.
How to execute an external command.
tcl
When using tclsh as a shell or repl, external commands that do not have the same name as a built-in or user defined function can be executed directly without using the exec command.
How to execute an external command and read the standard output into a variable.
What a library looks like.
How to import a library.
How to access the library path.
The environment variable which governs the library path.
How to declare a namespace.
The separator used in namespace names.
How to list the installed 3rd party packages; how to install a 3rd party package.
How to define a class.
How to instantiate a class.
How to create a blank object without any attributes or methods, or at least without any but the default attributes and methods.
How to set an object attribute.
How to get an object attribute.
How to define a method for an object.
How to invoke an object method.
How to make a copy of an object. Changes to the copy will not affect the original.
The syntax for an object literal.
Tcl Reference Manual
Tcl Standard Library
Tcl has some traits which will be familiar to anyone who has done Unix shell script programming:
(1) variables have a $ prefix except when values are assigned to them, in which case they are used unadorned:
set v 42puts $v
(2) statements consist of a command and zero or more arguments. Commands which are not built-in functions or user defined functions are resolved by looking for an external command in the search path and running it.
(3) the values are always stored in variables as strings. Commands which expect numeric arguments perform an implicit conversion, so there isn't much practical consequence for the developer.
(4) in the absence of quoting ("", {}, []) the arguments of a command are parsed into words using whitespace; commas are not used to separate arguments.
(5) square brackets [] must be used to execute a function and use its return value as an argument. A combination of square brackets [] and the expr command must be used to evaluate an expression and use its value as an argument:
puts [format "%10s" "lorem"]puts [expr 1 + 1]
Square brackets can be used to invoke an external command, but the value of the square brackets containing an external command is always the empty string: "".
Unlike shells, *, ?, ~ in variable names are not automatically expanded using the filesystem, but this behavior can be invoked with the glob command.
Lua 5.1 Reference Manual
Lua Tutorial Directory
The Lua REPL is actually a REL; that is, it doesn't print the value of statement. Furthermore expressions cannot in general be used in the position of a statement. An expression can be converted to a statement and printed by preceding it with an equals sign:
> =1 + 12> ="lorem ipsum"lorem ipsum
There is no built-in pretty printer for tables. All numbers are stored as double precision floats. The table type can be used as both an array and a dictionary.
Mozilla Developer Network: JavaScript
DOM 3 Core
DOM 3 Events
Node.js
JavaScript is embedded in an HTML document using the <script> tag. The browser interprets the contents of the tag as JavaScript:
<script> var sum = 1 + 2; alert('the sum is ' + sum);</script>
Alternatively the JavaScript can be in an external file named by the src attribute of the <script> tag:
<script src="foo.js"></script>
<script> tags can be placed in either the <head> or the <body> of an <html> document. They are executed as they are encountered by the browser. If there is a syntax error, then none of the JavaScript in the <script> tag will be executed. If there is an unhandled exception the browser stops execution of the <script> at that point. Neither syntax errors nor unhandled exceptions prevent the browser from executing JavaScript in subsequent <script> tags.
If placed in the <body>, a call to document.write() will insert HTML text into the location of document at the point of the <script> tag.
all javascript loaded event
sandboxing of JavaScript
http requests and DOM manipulation
In Chrome and Safari it is still possible for the user to execute JavaScript in the address bar:
javascript:alert('Hello World!')
An interpreted Groovy script can be nothing more than a few top level statements which are executed in order. The Groovy interpreter handles providing an entry point class and main method, compiling the source to Java byte code, and launching the JVM.
$ cat > hello.groovys = "Hello, World!"println(s)$ groovy hello.groovyHello, World!
Groovy classes can be placed in their own files and compiled to Java byte code explicitly. The resulting .class files depend on the groovy.jar and the asm.jar but otherwise can be used like .class files compiled from Java source files.
$ cat > Greeting.groovyclass Greeting { void say(name) { println("Hello, ${name}!") }}$ cat > UseGreeting.javapublic class UseGreeting { public static void main(String[] args) { Greeting g = new Greeting(); g.say(args[0]); }}$ groovyc Greeting.groovy$ javac UseGreeting.java$ java -cp.:/PATH/TO/groovy-2.2.1.jar:/PATH/TO/asm-4.1.jar UseGreeting FredHello, Fred!
All Groovy values have a Java type which can be inspected at runtime with the getClass() method.
A Groovy variable can optionally be declared to have a type. This places a constraint on the values which can be stored in the variable which is enforced at run time. The following code generates a org.codehaus.groovy.runtime.typehandling.GroovyCastException:
Integer i = 'foo'
Groovy does not use any of the Java primitive types directly: byte, short, int, long, float, double, boolean, char. Instead it used it uses the wrapper classes: Byte, Short, Integer, Long, Float, Double, Boolean, Char. Nevertheless it is still possible to use the primitive type in a variable declaration.
联系客服