php,python,javascript,perl,ruby的语法比较
2017-10-10 00:00
1241 查看
debugging and profiling |
java interop
sheet two:
file handles |
files |
directories |
processes and environment |
option parsing |
libraries and
java interop
version | ||||
---|---|---|---|---|
javascript | php | python | ruby | |
version used | 5.4; 5.5 | 2.7; 3.3 | 1.9; 2.0 | |
show version | $ node --version | $ php --version | $ python -V $ python --version | $ ruby --version |
implicit prologue | <script src="underscore.js"> </script> | none | import os, re, sys | none |
grammar and execution | ||||
javascript | php | python | ruby | |
interpreter | $ node foo.js | $ php -f foo.php | $ python foo.py | $ ruby foo.rb |
repl | $ node | $ php -a | $ python | $ irb |
command line program | $ node -e 'var sys = require("sys"); sys.puts("hi world!");' | $ php -r 'echo "hi\n";' | $ python -c 'print("hi")' | $ ruby -e 'puts "hi"' |
block delimiters | {} | {} | : and offside rule | {} do end |
statement separator | ; or newline newline not separator inside (), [], {}, "", '', or after binary operator newline sometimes not separator when following line would not parse as a valid statement | ; statements must be semicolon terminated inside {} | newline or ; newlines not separators inside (), [], {}, triple quote literals, or after backslash: \ | newline or ; newlines not separators inside (), [], {}, ``, '', "", or after binary operator or backslash: \ |
source code encoding | none | Python 3 source is 7fe0 UTF-8 by default # -*- coding: utf-8 -*- | Ruby 2.0 source is UTF-8 by default # -*- coding: utf-8 -*- | |
end-of-line comment | // comment | // comment # comment | # comment | # comment |
multiple line comment | /* line another line */ | /* comment line another line */ | use triple quote string literal: '''comment line another line''' | =begin comment line another line =end |
variables and expressions | ||||
javascript | php | python | ruby | |
local variable | var x = 1; | # in function body: $v = NULL; $a = []; $d = []; $x = 1; list($y, $z) = [2, 3]; | # in function body: v = None a, d = [], {} x = 1 y, z = 2, 3 | v = nil a, d = [], {} x = 1 y, z = 2, 3 |
regions which define lexical scope | top level: html page nestable: function | top level: function or method body nestable (with use clause): anonymous function body | nestable (read only): function or method body | top level: file class block module block method body nestable: anonymous function body anonymous block |
global variable | // assign without using var g = 1; function incr_global () { g++; } | list($g1, $g2) = [7, 8]; function swap_globals() { global $g1, $g2; list($g1, $g2) = [$g2, $g1]; } | g1, g2 = 7, 8 def swap_globals(): global g1, g2 g1, g2 = g2, g1 | $g1, $g2 = 7, 8 def swap_globals $g1, $g2 = $g2, $g1 end |
constant | none | define("PI", 3.14); | # uppercase identifiers # constant by convention PI = 3.14 | # warning if capitalized # identifier is reassigned PI = 3.14 |
assignment | x = 1; | $v = 1; | assignments can be chained but otherwise don't return values: v = 1 | v = 1 |
parallel assignment | none | list($x, $y, $z) = [1 ,2, 3]; # 3 is discarded: list($x, $y) = [1, 2, 3]; # $z set to NULL: list($x, $y, $z) = [1, 2]; | x, y, z = 1, 2, 3 # raises ValueError: x, y = 1, 2, 3 # raises ValueError: x, y, z = 1, 2 | x, y, z = 1, 2, 3 # 3 is discarded: x, y = 1, 2, 3 # z set to nil: x, y, z = 1, 2 |
swap | tmp = x; x = y; y = tmp; | list($x, $y) = [$y, $x]; | x, y = y, x | x, y = y, x |
compound assignment arithmetic, string, logical, bit | += -= *= /= none %= += none <<= >>= &= |= ^= | += -= *= none /= %= **= .= none &= |= none <<= >>= &= |= ^= | # do not return values: += -= *= /= //= %= **= += *= &= |= ^= <<= >>= &= |= ^= | += -= *= /= none %= **= += *= &&= ||= ^= <<= >>= &= |= ^= |
increment and decrement | var x = 1; var y = ++x; var z = --y; | $x = 1; $y = ++$x; $z = --$y; | none | x = 1 # x and y not mutated: y = x.succ z = y.pred |
null | null | NULL # case insensitive | None | nil |
null test | v === null | is_null($v) ! isset($v) | v == None v is None | v == nil v.nil? |
undefined variable | undefined | NULL | raises NameError | raises NameError |
conditional expression | x > 0 ? x : -x | $x > 0 ? $x : -$x | x if x > 0 else -x | x > 0 ? x : -x |
arithmetic and logic | ||||
javascript | php | python | ruby | |
true and false | true false | TRUE FALSE # case insensitive | True False | true false |
falsehoods | false null undefined "" 0 NaN | FALSE NULL 0 0.0 "" "0" [] | False None 0 0.0 '' [] {} | false nil |
logical operators | && || ! | && || ! lower precedence: and or xor | and or not | && || ! lower precedence: and or not |
relational operators | === !== < > >= <= perform type coercion: == != | == != or <> > < >= <= no conversion: === !== | relational operators are chainable: == != > < >= <= | == != > < >= <= |
min and max | Math.min(1, 2, 3) Math.max(1, 2, 3) Math.min.apply(Math, [1, 2, 3]) Math.max.apply(Math, [1, 2, 3]) | min(1, 2, 3) max(1, 2, 3) $a = [1, 2, 3] min($a) max($a) | min(1, 2, 3) max(1, 2, 3) min([1, 2, 3]) max([1, 2, 3]) | [1, 2, 3].min [1, 2, 3].max |
three value comparison | none | none | removed from Python 3: cmp(0, 1) cmp('do', 're') | 0 <=> 1 "do" <=> "re" |
arithmetic operators addition, subtraction, multiplication, float division, quotient, remainder | + - * / none % | + - * / none % | + - * see note // % Python 2 does not have an operator which performs float division on integers. In Python 3 / always performs float division. | + - * x.fdiv(y) / % |
integer division | Math.floor(x / y) | (int)(13 / 5) | 13 // 5 | 13 / 5 |
divmod | none | none | q, r = divmod(13, 5) | q, r = 13.divmod(5) |
integer division by zero | returns assignable value Infinity, NaN, or -Infinity depending upon whether dividend is positive, zero, or negative. There are literals for Infinity and NaN. | returns FALSE with warning | raises ZeroDivisionError | raises ZeroDivisionError |
float division | 13 / 5 | 13 / 5 | float(13) / 5 # Python 3: 13 / 5 | 13.to_f / 5 or 13.fdiv(5) |
float division by zero | same behavior as for integers | returns FALSE with warning | raises ZeroDivisionError | returns -Infinity, NaN, or Infinity |
power | Math.pow(2, 32) | pow(2, 32) | 2**32 | 2**32 |
sqrt | Math.sqrt(2) | sqrt(2) | import math math.sqrt(2) | include Math sqrt(2) |
sqrt -1 | NaN | NaN | # raises ValueError: import math math.sqrt(-1) # returns complex float: import cmath cmath.sqrt(-1) | raises Errno::EDOM |
transcendental functions | Math.exp Math.log Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2 | exp log sin cos tan asin acos atan atan2 | from math import exp, log, \ sin, cos, tan, asin, acos, atan, atan2 | include Math exp log sin cos tan asin acos atan atan2 |
transcendental constants π and e | Math.PI Math.E | M_PI M_E | import math math.pi math.e | include Math PI E |
float truncation | none Math.round(3.1) Math.floor(3.1) Math.ceil(3.1) | (int)$x round($x) ceil($x) floor($x) | import math int(x) int(round(x)) math.ceil(x) math.floor(x) | x.to_i x.round x.ceil x.floor |
absolute value | Math.abs(-3) | abs($x) | abs(x) | x.abs |
integer overflow | all numbers are floats | converted to float | becomes arbitrary length integer of typelong | becomes arbitrary length integer of typeBignum |
float overflow | Infinity | INF | raises OverflowError | Infinity |
rational construction | none | from fractions import Fraction x = Fraction(22, 7) | require 'rational' x = Rational(22, 7) | |
rational decomposition | none | x.numerator x.denominator | x.numerator x.denominator | |
complex construction | none | z = 1 + 1.414j | require 'complex' z = 1 + 1.414.im | |
complex decomposition real and imaginary component, argument, absolute value, conjugate | none | import cmath z.real z.imag cmath.phase(z) abs(z) z.conjugate() | z.real z.imag z.arg z.abs z.conj | |
random number uniform integer, uniform float, normal float | Math.floor(Math.random() * 100) Math.random() none | rand(0,99) lcg_value() none | import random random.randint(0, 99) random.random() random.gauss(0, 1) | rand(100) rand none |
random seed set, get, restore | none | srand(17); none | import random random.seed(17) seed = random.getstate() random.setstate(seed) | srand(17) seed = srand srand(seed) |
bit operators | << >> & | ^ ~ | << >> & | ^ ~ | << >> & | ^ ~ | << >> & | ^ ~ |
binary, octal, and hex literals | none 052 // deprecated 0x2a | 0b101010 052 0x2a | 0b101010 052 0x2a | 0b101010 052 0x2a |
radix convert integer to and from string with radix | (42).toString(7) ?? | base_convert("42", 10, 7); base_convert("60", 7, 10); | none int("60", 7) | 42.to_s(7) "60".to_i(7) |
strings | ||||
javascript | php | python | ruby | |
string type | String | string | str | String |
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"' "don't " 'say "no"' |
newline in literal | yes | 'first line second line' "first line second line" | triple quote literals only: '''first line second line''' """first line second line""" | 'first line second line' "first line second line" |
literal escapes | single and double quotes: \b \f \n \r \t \v \uhhhh \xhh \" \' \\ | double quoted: \f \n \r \t \v \xhh \$ \" \\ \ooo single quoted: \' \\ | single and double quoted: \newline \\ \' \" \a \b \f \n \r \t \v \ooo \xhh Python 3: \uhhhh \Uhhhhhhhh | double quoted: \a \b \cx \e \f \n \r \s \t \v \xhh \ooo\uhhhh \u{hhhhh} single quoted: \' \\ |
here document | none | $word = "amet"; $s = <<<EOF lorem ipsum dolor sit $word EOF; | none | word = "amet" s = <<EOF lorem ipsum dolor sit #{word} EOF |
variable interpolation | // None; use string concatenation. // Both of these expressions are '11': 1 + "1" "1" + 1 | $count = 3; $item = "ball"; echo "$count ${item}s\n"; | count = 3 item = 'ball' print('{count} {item}s'.format( **locals())) | count = 3 item = "ball" puts "#{count} #{item}s" |
expression interpolation | none | none | '1 + 1 = {}'.format(1 + 1) | "1 + 1 = #{1 + 1}" |
format string | // None; use string concatenation. // Evaluates to "12.35": 12.3456.toFixed(2) | $fmt = "lorem %s %d %f"; sprintf($fmt, "ipsum", 13, 3.7); | 'lorem %s %d %f' % ('ipsum', 13, 3.7) fmt = 'lorem {0} {1} {2}' fmt.format('ipsum', 13, 3.7) | "lorem %s %d %f" % ["ipsum", 13, 3.7] |
are strings mutable? | no | $s = "bar"; $s2 = $s; # sets s to "baz"; s2 is unchanged: $s[2] = "z"; | no | s = "bar" s2 = s # sets s and s2 to "baz": s[2] = "z" |
copy string | none | $s2 = $s; | none | s = "bar" s2 = s.clone # s2 is not altered: s[2] = "z" |
concatenate | s = "Hello, " + "World!"; | $s = "Hello, "; $s2 = $s . "World!"; | s = 'Hello, ' s2 = s + 'World!' # juxtaposition can be used to # concatenate literals: s2 = 'Hello, ' "World!" | s = "Hello, " s2 = s + "World!" # juxtaposition can be used to # concatenate literals: s2 = "Hello, " 'World!' |
replicate | var hbar = Array(80).join("-"); | $hbar = str_repeat("-", 80); | hbar = '-' * 80 | hbar = "-" * 80 |
translate case to upper, to lower | "lorem".toUpperCase() "LOREM".toLowerCase() | strtoupper("lorem") strtolower("LOREM") | 'lorem'.upper() 'LOREM'.lower() | "lorem".upcase "LOREM".downcase |
capitalize string, words | none | ucfirst("lorem") ucwords("lorem ipsum") | import string 'lorem'.capitalize() string.capwords('lorem ipsum') | "lorem".capitalize none |
trim both sides, left, right | " lorem ".trim() # some browsers: " lorem".trimLeft() "lorem ".trimRight() | trim(" lorem ") ltrim(" lorem") rtrim("lorem ") | ' lorem '.strip() ' lorem'.lstrip() 'lorem '.rstrip() | " lorem ".strip " lorem".lstrip "lorem ".rstrip |
pad on right, on left, centered | none | str_pad("lorem", 10) str_pad("lorem", 10, " ", STR_PAD_LEFT) str_pad("lorem", 10, " ", STR_PAD_BOTH) | 'lorem'.ljust(10) 'lorem'.rjust(10) 'lorem'.center(10) | "lorem".ljust(10) "lorem".rjust(10) "lorem".center(10) |
number to string | "value: " + 8 | "value: " . 8 | 'value: ' + str(8) | "value: " + 8.to_s |
string to number | 7 + parseInt("12", 10) 73.9 + parseFloat(".037") // 12: parseInt("12A") // NaN: parseInt("A") | 7 + "12" 73.9 + ".037" # 12: 0 + "12A" # 0: 0 + "A" | 7 + int('12') 73.9 + float('.037') # raises ValueError: int('12A') # raises ValueError: int('A') | 7 + "12".to_i 73.9 + ".037".to_f # 12: "12A".to_i # 0: "A".to_i |
string join | ["do", "re", "mi"].join(" ") | $a = ["do", "re", "mi", "fa"]; implode(" ", $a) | ' '.join(['do', 're', 'mi', 'fa']) # raises TypeError: ' '.join([1, 2, 3]) | %w(do re mi fa).join(' ') # implicitly converted to strings: [1, 2, 3].join(' ') |
split | // [ "do", "re", "", "mi", "" ]: "do re mi ".split(" ") // [ "do", "re", "mi", "" ]: "do re mi ".split(/\s+/) | # [ "do", "re", "", "mi", "" ]: explode(" ", "do re mi ") # [ "do", "re", "mi", "" ]: preg_split('/\s+/', "do re mi ") | # ['do', 're', '', 'mi', '']: 'do re mi '.split(' ') # ['do', 're', 'mi']: 'do re mi '.split() | # ["do", "re", "", "mi"]: "do re mi ".split(/ /) # ["do", "re", "mi"]: "do re mi ".split |
split in two | none | preg_split('/\s+/', "do re mi fa", 2) | 'do re mi fa'.split(None, 1) | "do re mi fa".split(/\s+/, 2) |
split and keep delimiters | none | preg_split('/(\s+)/', "do re mi fa", NULL, PREG_SPLIT_DELIM_CAPTURE) | re.split('(\s+)', 'do re mi fa') | "do re mi fa".split(/(\s+)/) |
prefix and suffix test | "foobar".startsWith("foo") "foobar".endsWith("bar") | 'foobar'.startswith('foo') 'foobar'.endswith('bar') | 'foobar'.start_with?('foo') 'foobar'.end_with?('bar') | |
length | "lorem".length | strlen("lorem") | len('lorem') | "lorem".length "lorem".size |
index of substring first, last | // returns -1 if not found: "lorem ipsum".indexOf("ipsum") | # returns FALSE if not found: strpos("do re re", "re") strrpos("do re re", "re") | # raises ValueError if not found: 'do re re'.index('re') 'do re re'.rindex('re') # returns -1 if not found: 'do re re'.find('re') 'do re re'.rfind('re') | # returns nil if not found: "do re re".index("re") "do re re".rindex("re") |
extract substring by start and length, by start and end, by successive starts | "lorem ipsum".substr(6, 5) "lorem ipsum".substring(6, 11) | substr("lorem ipsum", 6, 5) none none | none none 'lorem ipsum'[6:11] | "lorem ipsum"[6, 5] "lorem ipsum"[6..10] "lorem ipsum"[6...11] |
character lookup | "lorem ipsum"[6] | # syntax error to use index notation # directly on string literal: $s = "lorem ipsum"; $s[6]; | 'lorem ipsum'[6] | "lorem ipsum"[6] |
chr and ord | String.fromCharCode(65) "A".charCodeAt(0) | chr(65) ord("A") | chr(65) ord('A') | 65.chr "A".ord |
to array of characters | "abcd".split("") | str_split("abcd") | list('abcd') | "abcd".split("") |
translate characters | none | $ins = implode(range("a", "z")); $outs = substr($ins, 13, 13) . substr($ins, 0, 13); strtr("hello", $ins, $outs) | from string import lowercase as ins from string import maketrans outs = ins[13:] + ins[:13] 'hello'.translate(maketrans(ins,outs)) | "hello".tr("a-z", "n-za-m") |
delete characters | none | $vowels = str_split("aeiou"); $s = "disemvowel me"; $s = str_replace($vowels, "", $s); | "disemvowel me".translate(None, "aeiou") | "disemvowel me".delete("aeiou") |
squeeze characters | none | $s = "too much space"; $s = = preg_replace('/(\s)+/', '\1', $s); | re.sub('(\s)+', r'\1','too much space') | "too much space".squeeze(" ") |
regular expressions | ||||
javascript | 3ff0 php | python | ruby | |
literal, custom delimited literal | /lorem|ipsum/ | '/lorem|ipsum/' '(/etc/hosts)' | re.compile('lorem|ipsum') none | /lorem|ipsum/ %r(/etc/hosts) |
character class abbreviations | . \d \D \s \S \w \W | . \d \D \h \H \s \S \v \V \w \W | . \d \D \s \S \w \W | . \d \D \h \H \s \S \w \W |
anchors | ^ $ \b \B | ^ $ \A \b \B \z \Z | ^ $ \A \b \B \Z | ^ $ \A \b \B \z \Z |
match test | if (s.match(/1999/)) { alert("party!"); } | if (preg_match('/1999/', $s)) { echo "party!\n"; } | if re.search('1999', s): print('party!') | if /1999/.match(s) puts "party!" end |
case insensitive match test | "Lorem".match(/lorem/i) | preg_match('/lorem/i', "Lorem") | re.search('lorem', 'Lorem', re.I) | /lorem/i.match("Lorem") |
modifiers | g i m | e i m s x | re.I re.M re.S re.X | i o m x |
substitution | s = "do re mi mi mi"; s.replace(/mi/g, "ma"); | $s = "do re mi mi mi"; $s = preg_replace('/mi/', "ma", $s); | s = 'do re mi mi mi' s = re.compile('mi').sub('ma', s) | s = "do re mi mi mi" s.gsub!(/mi/, "ma") |
match, prematch, postmatch | m = /\d{4}/.exec(s); if (m) { match = m[0]; # no prematch or postmatch } | none | m = re.search('\d{4}', s) if m: match = m.group() prematch = s[0:m.start(0)] postmatch = s[m.end(0):len(s)] | m = /\d{4}/.match(s) if m match = m[0] prematch = m.pre_match postmatch = m.post_match end |
group capture | 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"; $rx = '/(\d{4})-(\d{2})-(\d{2})/'; preg_match($rx, $s, $m); list($_, $yr, $mo, $dy) = $m; | rx = '(\d{4})-(\d{2})-(\d{2})' m = re.search(rx, '2010-06-03') yr, mo, dy = m.groups() | rx = /(\d{4})-(\d{2})-(\d{2})/ m = rx.match("2010-06-03") yr, mo, dy = m[1..3] |
named group capture | none | $s = "foo.txt"; $rx = '/^(?P<file>.+)\.(?P<suffix>.+)$/'; preg_match($rx, $s, $m); $m["file"] $m["suffix"] | rx = '^(?P<file>.+)\.(?P<suffix>.+)$' m = re.search(rx, ''foo.txt') m.groupdict()['file'] m.groupdict()['suffix'] | rx = /^(?<file>.+)\.(?<suffix>.+)$/ m = rx.match('foo.txt') m["file"] m["suffix"] |
scan | var a = "dolor sit amet".match(/\w+/g); | $s = "dolor sit amet"; preg_match_all('/\w+/', $s, $m); $a = $m[0]; | s = 'dolor sit amet' a = re.findall('\w+', s) | a = "dolor sit amet".scan(/\w+/) |
backreference in match and substitution | /(\w+) \1/.exec("do do") "do re".replace(/(\w+) (\w+)/, '$2 $1') | preg_match('/(\w+) \1/', "do do") $s = "do re"; $rx = '/(\w+) (\w+)/'; $s = preg_replace($rx, '\2 \1', $s); | none rx = re.compile('(\w+) (\w+)') rx.sub(r'\2 \1', 'do re') | /(\w+) \1/.match("do do") "do re".sub(/(\w+) (\w+)/, '\2 \1') |
recursive regex | none | '/\(([^()]*|($R))\)/' | none | /(?<foo>\(([^()]*|\g<foo>)*\))/ |
dates and time | ||||
javascript | php | python | ruby | |
broken-down datetime type | Date | DateTime | datetime.datetime | Time |
current datetime | var t = new Date(); | $t = new DateTime("now"); $utc_tmz = new DateTimeZone("UTC"); $utc = new DateTime("now", $utc_tmz); | import datetime t = datetime.datetime.now() utc = datetime.datetime.utcnow() | t = Time.now utc = Time.now.utc |
current unix epoch | (new Date()).getTime() / 1000 | $epoch = time(); | import datetime t = datetime.datetime.now() epoch = int(t.strftime("%s")) | epoch = Time.now.to_i |
broken-down datetime to unix epoch | Math.round(t.getTime() / 1000) | $epoch = $t->getTimestamp(); | from datetime import datetime as dt epoch = int(t.strftime("%s")) | epoch = t.to_i |
unix epoch to broken-down datetime | var epoch = 1315716177; var t2 = new Date(epoch * 1000); | $t2 = new DateTime(); $t2->setTimestamp(1304442000); | t = dt.fromtimestamp(1304442000) | t = Time.at(1304442000) |
format datetime | none | strftime("%Y-%m-%d %H:%M:%S", $epoch); date("Y-m-d H:i:s", $epoch); $t->format("Y-m-d H:i:s"); | t.strftime('%Y-%m-%d %H:%M:%S') | t.strftime("%Y-%m-%d %H:%M:%S") |
parse datetime | none | $fmt = "Y-m-d H:i:s"; $s = "2011-05-03 10:00:00"; $t = DateTime::createFromFormat($fmt, $s); | from datetime import datetime s = '2011-05-03 10:00:00' fmt = '%Y-%m-%d %H:%M:%S' t = datetime.strptime(s, fmt) | require 'date' s = "2011-05-03 10:00:00" fmt = "%Y-%m-%d %H:%M:%S" t = DateTime.strptime(s, fmt).to_time |
parse datetime w/o format | var t = new Date("July 7, 1999"); | $epoch = strtotime("July 7, 1999"); | # pip install python-dateutil import dateutil.parser s = 'July 7, 1999' t = dateutil.parser.parse(s) | require 'date' s = "July 7, 1999" t = Date.parse(s).to_time |
date parts | t.getFullYear() t.getMonth() + 1 t.getDate() # getDay() is day of week | (int)$t->format("Y") (int)$t->format("m") (int)$t->format("d") | t.year t.month t.day | t.year t.month t.day |
time parts | t.getHours() t.getMinutes() t.getSeconds() | (int)$t->format("H") (int)$t->format("i") (int)$t->format("s") | t.hour t.minute t.second | t.hour t.min t.sec |
build broken-down datetime | 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); | import datetime yr = 1999 mo = 9 dy = 10 hr = 23 mi = 30 ss = 0 t = datetime.datetime(yr, mo, dy, hr, mi, ss) | yr = 1999 mo = 9 dy = 10 hr = 23 mi = 30 ss = 0 t = Time.new(yr, mo, dy, hr, mi, ss) | |
datetime subtraction | number containing time difference in milliseconds | # DateInterval object if diff method used: $fmt = "Y-m-d H:i:s"; $s = "2011-05-03 10:00:00"; $then =DateTime::createFromFormat($fmt, $s); $now = new DateTime("now"); $interval = $now->diff($then); | datetime.timedelta object use total_seconds() method to convert to float representing difference in seconds | Float containing time difference in seconds |
add duration | var t1 = new Date(); var delta = (10 * 60 + 3) * 1000; var t2 = new Date(t1.getTime() + delta); | $now = new DateTime("now"); $now->add(new DateInterval("PT10M3S"); | import datetime delta = datetime.timedelta( minutes=10, seconds=3) t = datetime.datetime.now() + delta | require 'date/delta' s = "10 min, 3 s" delta = Date::Delta.parse(s).in_secs t = Time.now + delta |
local time zone determination | # DateTime objects can be instantiated without # specifying the time zone if a default is set: $s = "America/Los_Angeles"; date_default_timezone_set($s); | a datetime object has no time zone information unless a tzinfo object is provided when it is created | if no time zone is specified the local time zone is used | |
nonlocal time zone | # pip install pytz import pytz import datetime tmz = pytz.timezone('Asia/Tokyo') utc = datetime.datetime.utcnow() utc_dt = datetime.datetime( *utc.timetuple()[0:5], tzinfo=pytz.utc) jp_dt = utc_dt.astimezone(tmz) | # gem install tzinfo require 'tzinfo' tmz = TZInfo::Timezone.get("Asia/Tokyo") jp_time = tmz.utc_to_local(Time.now.utc) | ||
time zone info name and UTC offset | $tmz = date_timezone_get($t); timezone_name_get($tmz); date_offset_get($t) / 3600; | import time tm = time.localtime() time.tzname[tm.tm_isdst] (time.timezone / -3600) + tm.tm_isdst | t.zone t.utc_offset / 3600 | |
daylight savings test | $t->format("I"); | import time tm = time.localtime() tm.tm_isdst | t.dst? | |
microseconds | list($frac, $sec) = explode(" ", microtime()); $usec = $frac * 1000 * 1000; | t.microsecond | t.usec | |
sleep | none | # a float argument will be truncated # to an integer: sleep(1); | import time time.sleep(0.5) | sleep(0.5) |
timeout | use set_time_limit to limit execution time of the entire script; usestream_set_timeout to limit time spent reading from a stream opened with fopenor fsockopen | import signal, time class Timeout(Exception): pass def timeout_handler(signo, fm): raise Timeout() signal.signal(signal.SIGALRM, timeout_handler) try: signal.alarm(5) might_take_too_long() except Timeout: pass signal.alarm(0) | require 'timeout' begin Timeout.timeout(5) do might_take_too_long end rescue Timeout::Error end | |
resizable arrays | ||||
javascript | php | python | ruby | |
literal | a = [1, 2, 3, 4] | $a = [1, 2, 3, 4]; # older syntax: $a = array(1, 2, 3, 4); | a = [1, 2, 3, 4] | a = [1, 2, 3, 4] # a = ['do', 're', 'mi'] a = %w(do re mi) |
size | a.length | count($a) | len(a) | a.size a.length # same as size |
empty test | // TypeError if a is null or undefined: a.length === 0 | # NULL tests as empty: !$a | # None tests as empty: not a | # NoMethodError if a is nil: a.empty? |
lookup | a[0] | $a[0] # PHP uses the same type for arrays and # dictionaries; indices can be negative # integers or strings | a[0] # returns last element: a[-1] | a[0] # returns last element: a[-1] |
update | a[0] = "lorem" | $a[0] = "lorem"; | a[0] = 'lorem' | a[0] = "lorem" |
out-of-bounds behavior | returns undefined | $a = []; # evaluates as NULL: $a[10]; # increases array size to one: $a[10] = "lorem"; | a = [] # raises IndexError: a[10] # raises IndexError: a[10] = 'lorem' | a = [] # evaluates as nil: a[10] # increases array size to 11: a[10] = "lorem" |
element index first and last occurrence | // return -1 if not found: [6, 7, 7, 8].indexOf(7) [6, 7, 7, 8].lastIndexOf(7) | $a = ["x", "y", "y", "z"]; # returns FALSE if not found: $i = array_search("y", $a, TRUE); none | a = ['x', 'y', 'y', 'z'] # raises ValueError if not found: a.index('y') none | a = %w(x y y z) # return nil if not found: a.index('y') a.rindex('y') |
slice by endpoints, by length | // select 3rd and 4th elements: ["a", "b", "c", "d"].slice(2, 4) none | # select 3rd and 4th elements: none array_slice($a, 2, 2) | # select 3rd and 4th elements: a[2:4] a[2:2 + 2] | # select 3rd and 4th elements: a[2..3] a[2, 2] |
slice to end | ["a", "b", "c", "d"].slice(1) | array_slice($a, 1) | a[1:] | a[1..-1] |
manipulate back | a = [6, 7, 8]; a.push(9); i = a.pop(); | $a = [6, 7, 8]; array_push($a, 9); $a[] = 9; # same as array_push array_pop($a); | a = [6, 7, 8] a.append(9) a.pop() | a = [6, 7, 8] a.push(9) a << 9 # same as push a.pop |
manipulate front | a = [6, 7, 8]; a.unshift(5); i = a.shift(); | $a = [6, 7, 8]; array_unshift($a, 5); array_shift($a); | a = [6, 7, 8] a.insert(0, 5) a.pop(0) | a = [6, 7, 8] a.unshift(5) a.shift |
concatenate | a = [1, 2, 3].concat([4, 5, 6]); | $a = [1, 2, 3]; $a2 = array_merge($a, [4, 5, 6]); $a = array_merge($a, [4, 5, 6]); | a = [1, 2, 3] a2 = a + [4, 5, 6] a.extend([4, 5, 6]) | a = [1, 2, 3] a2 = a + [4, 5, 6] a.concat([4, 5, 6]) |
replicate | none | a = [None] * 10 a = [None for i in range(0, 10)] | a = [nil] * 10 a = Array.new(10, nil) | |
copy address copy, shallow copy, deep copy | a = [1, 2, [3, 4]]; a2 = a; a3 = a.slice(0); a4 = JSON.parse(JSON.stringify(a)); | $a = [1, 2, [3, 4]]; $a2 =& $a; none $a4 = $a; | import copy a = [1,2,[3,4]] a2 = a a3 = list(a) a4 = copy.deepcopy(a) | a = [1,2,[3,4]] a2 = a a3 = a.dup a4 = Marshal.load(Marshal.dump(a)) |
array as function argument | parameter contains address copy | parameter contains deep copy | parameter contains address copy | parameter contains address copy |
iterate over elements | _.each([1, 2, 3], function(n) { alert(n); }) | foreach ([1, 2, 3] as $i) { echo "$i\n"; } | for i in [1, 2, 3]: print(i) | [1, 2, 3].each { |i| puts i } |
iterate over indices and elements | var len = a.length; for (var i = 0; i < len; i++ ) { alert(a[i]); } | $a = ["do", "re", "mi" "fa"]; foreach ($a as $i => $s) { echo "$s at index $i\n"; } | a = ['do', 're', 'mi', 'fa'] for i, s in enumerate(a): print('%s at index %d' % (s, i)) | a = %w(do re mi fa) a.each_with_index do |s, i| puts "#{s} at index #{i}" end |
iterate over range | not space efficient; use C-style for loop | not space efficient; use C-style for loop | # use range() in Python 3: for i in xrange(1, 1000001): code | (1..1_000_000).each do |i| code end |
instantiate range as array | var a = _.range(1, 10); | $a = range(1, 10); | a = range(1, 11) Python 3: a = list(range(1, 11)) | a = (1..10).to_a |
reverse non-destructive, in-place | var a = [1, 2, 3]; a.reverse(); | $a = [1, 2, 3]; array_reverse($a); $a = array_reverse($a); | a = [1, 2, 3] a[::-1] a.reverse() | a = [1, 2, 3] a.reverse a.reverse! |
sort non-destructive, in-place, custom comparision | var a = [3, 1, 4, 2]; a.sort(); | $a = ["b", "A", "a", "B"]; none sort($a); none, but usort sorts in place | a = ['b', 'A', 'a', 'B'] sorted(a) a.sort() # custom binary comparision # removed from Python 3: a.sort(key=str.lower) | a = %w(b A a B) a.sort a.sort! a.sort do |x, y| x.downcase <=> y.downcase end |
dedupe non-destructive, in-place | var a = [1, 2, 2, 3]; var a2 = _.uniq(a); a = _.uniq(a); | $a = [1, 2, 2, 3]; $a2 = array_unique($a); $a = array_unique($a); | a = [1, 2, 2, 3] a2 = list(set(a)) a = list(set(a)) | a = [1, 2, 2, 3] a2 = a.uniq a.uniq! |
membership | _.contains(a, 7) | in_array(7, $a) | 7 in a | a.include?(7) |
intersection | _.intersection([1, 2], [2, 3, 4]) | $a = [1, 2]; $b = [2, 3, 4] array_intersect($a, $b) | {1, 2} & {2, 3, 4} | [1, 2] & [2 ,3, 4] |
union | _.union([1, 2], [2, 3, 4]) | $a1 = [1, 2]; $a2 = [2, 3, 4]; array_unique(array_merge($a1, $a2)) | {1, 2} | {2, 3, 4} | [1, 2] | [2, 3, 4] |
relative complement, symmetric difference | _.difference([1, 2, 3], [2]) none | $a1 = [1, 2, 3]; $a2 = [2]; array_values(array_diff($a1, $a2)) none | {1, 2, 3} - {2} {1, 2} ^ {2, 3, 4} | require 'set' [1, 2, 3] - [2] Set[1, 2] ^ Set[2 ,3, 4] |
map | // callback gets 3 args: // value, index, array a.map(function(x) { return x * x }) | array_map(function ($x) { return $x * $x; }, [1, 2, 3]) | map(lambda x: x * x, [1, 2, 3]) # or use list comprehension: [x * x for x in [1, 2, 3]] | [1, 2, 3].map { |o| o * o } |
filter | a.filter(function(x) { return x > 1 }) | array_filter([1, 2, 3], function ($x) { return $x>1; }) | filter(lambda x: x > 1, [1, 2, 3]) # or use list comprehension: [x for x in [1, 2, 3] if x > 1] | [1, 2, 3].select { |o| o > 1 } |
reduce | a.reduce(function(m, o) { return m + o; }, 0) | array_reduce([1, 2, 3], function($x,$y) { return $x + $y; }, 0) | # import needed in Python 3 only from functools import reduce reduce(lambda x, y: x + y, [1, 2, 3], 0) | [1, 2, 3].inject(0) { |m, o| m + o } |
universal and existential tests | var a = [1, 2, 3, 4]; var even = function(x) { return x % 2 == 0; }; a.every(even) a.some(even) | use array_filter | all(i % 2 == 0 for i in [1, 2, 3, 4]) any(i % 2 == 0 for i in [1, 2, 3, 4]) | [1, 2, 3, 4].all? {|i| i.even? } [1, 2, 3, 4].any? {|i| i.even? } |
shuffle and sample | var a = [1, 2, 3, 4]; a = _.shuffle(a); var samp = _.sample([1, 2, 3, 4], 2); | $a = [1, 2, 3, 4]; shuffle($a); $samp = array_rand(|[1, 2, 3, 4], 2); | from random import shuffle, sample a = [1, 2, 3, 4] shuffle(a) samp = sample([1, 2, 3, 4], 2) | [1, 2, 3, 4].shuffle! samp = [1, 2, 3, 4].sample(2) |
flatten one level, completely | var a = [1, [2, [3, 4]]]; var a2 = _.flatten(a, true); var a3 = _.flatten(a); | none | none | a = [1, [2, [3, 4]]] a2 = a.flatten(1) a3 = a.flatten |
zip | var a = _.zip( [1, 2, 3], ["a", "b", "c"]); | $a = array_map(NULL, [1, 2, 3], ["a", "b", "c"]); | a = zip([1, 2, 3], ['a', 'b', 'c']) | a = [1, 2, 3].zip(["a", "b", "c"]) |
dictionaries | ||||
javascript | php | python | ruby | |
literal | 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]; # older syntax: $d = array("t" => 1, "f" => 0); | d = {'t': 1, 'f': 0} | d = {'t' => 1, 'f' => 0} # keys are symbols: symbol_to_int = {t: 1, f: 0} |
size | var size = 0; for (var k in d) { if (d.hasOwnProperty(k)) size++; } | count($d) | len(d) | d.size d.length # same as size |
lookup | d.t d["t"] | $d["t"] | d['t'] | d['t'] |
update | d["t"] = 2; d.t = 2; | $d["t"] = 2; | d['t'] = 2 | d['t'] = 2 |
missing key behavior | var d = {}; // sets s to undefined: var s = d["lorem"]; // adds key/value pair: d["lorem"] = "ipsum"; | $d = []; # sets $s to NULL: $s = $d["lorem"]; # adds key/value pair: $d["lorem"] = "ipsum"; | d = {} # raises KeyError: s = d['lorem'] # adds key/value pair: d['lorem'] = 'ipsum' | d = {} # sets s to nil: s = d['lorem'] # adds key/value pair: d['lorem'] = 'ipsum' |
is key present | d.hasOwnProperty("t"); | array_key_exists("y", $d); | 'y' in d | d.key?('y') |
delete | delete d["t"]; delete d.t; | $d = [1 => "t", 0 => "f"]; unset($d[1]); | d = {1: True, 0: False} del d[1] | d = {1 => true, 0 => false} d.delete(1) |
from array of pairs, from even length array | var a = [["a", 1], ["b", 2], ["c", 3]]; var d = _.object(a); none | a = [['a', 1], ['b', 2], ['c', 3]] d = dict(a) a = ['a', 1, 'b', 2, 'c', 3] d = dict(zip(a[::2], a[1::2])) | a = [['a', 1], ['b', 2], ['c', 3]] d = Hash[a] a = ['a', 1, 'b', 2, 'c', 3] d = Hash[*a] | |
merge | var d1 = {"a": 1, "b": 2}; var d2 = {"c": 3, "d": 4}; d1 = _.extend(d1, d2); | $d1 = ["a" => 1, "b" => 2]; $d2 = ["b" => 3, "c" => 4]; $d1 = array_merge($d1, $d2); | d1 = {'a': 1, 'b': 2} d2 = {'b': 3, 'c': 4} d1.update(d2) | d1 = {'a' => 1, 'b' => 2} d2 = {'b' => 3, 'c' => 4} d1.merge!(d2) |
invert | var to_num = {'t': 1, 'f': 0}; var to_let = _.invert(to_num); | $to_num = ["t" => 1, "f" => 0]; $to_let = array_flip($to_num); | to_num = {'t': 1, 'f': 0} # dict comprehensions added in 2.7: to_let = {v: k for k, v in to_num.items()} | to_num = {'t' => 1, 'f' => 0} to_let = to_num.invert |
iterate | for (var k in d) { use k or d[k] } | foreach ($d as $k => $v) { code } | for k, v in d.iteritems(): code Python 3: for k, v in d.items(): code | d.each do |k,v| code end |
keys and values as arrays | _.keys(d) _.values(d) | array_keys($d) array_values($d) | d.keys() d.values() Python 3: list(d.keys()) list(d.values()) | d.keys d.values |
sort by values | function cmp2(a, b) { if (a[1] < b[1]) { return -1; } if (a[1] > b[1]) { return 1; } return 0; } for (p in _.pairs(d).sort(cmp2)) { alert(p[0] + ": " + p[1]); } | asort($d); foreach ($d as $k => $v) { print "$k: $v\n"; } | from operator import itemgetter pairs = sorted(d.iteritems(), key=itemgetter(1)) for k, v in pairs: print('{}: {}'.format(k, v)) | d.sort_by { |k, v| v }.each do |k, v| puts "#{k}: #{v}" end |
default value, computed value | none | $counts = []; $counts['foo'] += 1; extend ArrayObject for computed values and defaults other than zero or empty string. | from collections import defaultdict counts = defaultdict(lambda: 0) counts['foo'] += 1 class Factorial(dict): def __missing__(self, k): if k > 1: return k * self[k-1] else: return 1 factorial = Factorial() | counts = Hash.new(0) counts['foo'] += 1 factorial = Hash.new do |h,k| k > 1 ? k * h[k-1] : 1 end |
functions | ||||
javascript | php | python | ruby | |
define | function add(x, y) { return x+y; } | function add3($x1, $x2, $x3) { return $x1 + $x2 + $x3; } | def add3(x1, x2, x3): return x1 + x2 + x3 | def add3(x1, x2, x3) x1 + x2 + x3 end # parens are optional and customarily # omitted when defining functions # with no parameters |
invoke | add(1, 2) | add3(1, 2, 3); # function names are case insensitive: ADD3(1, 2, 3); | add3(1, 2, 3) | add3(1, 2, 3) # parens are optional: add3 1, 2, 3 |
missing argument behavior | set to undefined | set to NULL with warning | raises TypeError if number of arguments doesn't match function arity | raises ArgumentError if number of arguments doesn't match function arity |
extra argument behavior | raises TypeError if number of arguments doesn't match function arity | raises ArgumentError if number of arguments doesn't match function arity | ||
default argument | none | function my_log($x, $base=10) { return log($x) / log($base); } my_log(42); my_log(42, M_E); | import math def my_log(x, base=10): return math.log(x) / math.log(base) my_log(42) my_log(42, math.e) | def my_log(x, base=10) Math.log(x) / Math.log(base) end my_log(42) my_log(42, Math::E) |
variadic function | args in arguments[0], arguments[1], … with number of args in arguments.length | function first_and_last() { $arg_cnt = func_num_args(); if ($arg_cnt >= 1) { $n = func_get_arg(0); echo "first: " . $n . "\n"; } if ($arg_cnt >= 2) { $a = func_get_args(); $n = $a[$arg_cnt-1]; echo "last: " . $n . "\n"; } } | def first_and_last(*a): if len(a) >= 1: print('first: ' + str(a[0])) if len(a) >= 2: print('last: ' + str(a[-1])) | def first_and_last(*a) if a.size >= 1 puts "first: #{a[0]}" end if a.size >= 2 puts "last: #{a[-1]}" end end |
pass array elements as separate arguments | none | $a = [1, 2, 3]; call_user_func_array("add3", $a); | a = [2, 3] add3(1, *a) # splat operator can only be used once # and must appear after other # unnamed arguments | a = [2, 3] add3(1, *a) # splat operator can be used multiple # times and can appear before regular # arguments |
parameter alias | none | function first_and_second(&$a) { return [$a[0], $a[1]]; } | none | none |
named parameters | none | none | def fequal(x, y, eps=0.01): return abs(x - y) < eps fequal(1.0, 1.001) fequal(1.0, 1.001, eps=0.1**10) | def fequal(x, y, opts={}) eps = opts[:eps] || 0.01 (x - y).abs < eps end fequal(1.0, 1.001) fequal(1.0, 1.001, :eps=>0.1**10) # Ruby 2.0: def fequals(x, y, eps: 0.01) (x - y).abs < eps end fequals(1.0, 1.001) fequals(1.0, 1.001, eps: 0.1**10) |
return value | return arg or undefined. If invoked with new and return value not an object, returns this | return arg or NULL | return arg or None | return arg or last expression evaluated |
multiple return values | none | function first_and_second(&$a) { return [$a[0], $a[1]]; } $a = [1, 2, 3]; list($x, $y) = first_and_second($a); | def first_and_second(a): return a[0], a[1] x, y = first_and_second([1, 2, 3]) | def first_and_second(a) return a[0], a[1] end x, y = first_and_second([1, 2, 3]) |
anonymous function literal | var sqr = function(x) { return x*x; } | $sqr = function ($x) { return $x * $x; }; | # body must be an expression: sqr = lambda x: x * x | sqr = lambda { |x| x * x } |
invoke anonymous function | sqr(2) | $sqr(2) | sqr(2) | sqr.call(2) or sqr[2] |
function as value | var func = add; | $func = "add"; | func = add | func = lambda { |*args| add(*args) } |
function with private state | function counter() { counter.i += 1; return counter.i; } counter.i = 0; alert(counter()); | function counter() { static $i = 0; return ++$i; } echo counter(); | # state not private: def counter(): counter.i += 1 return counter.i counter.i = 0 print(counter()) | none |
closure | function make_counter() { var i = 0; return function() { i += 1; return i; } } | function make_counter() { $i = 0; return function () use (&$i) { return ++$i; }; } $nays = make_counter(); echo $nays(); | # Python 3: def make_counter(): i = 0 def counter(): nonlocal i i += 1 return i return counter nays = make_counter() | def make_counter i = 0 return lambda { i +=1; i } end nays = make_counter puts nays.call |
generator | # PHP 5.5: function make_counter() { $i = 0; while (1) { yield ++$i; } } $nays = make_counter(); # does not return a value: $nays->next(); # runs generator if generator has not # yet yielded: echo $nays->current(); | # The itertools library contains # standard generators. # c.f. itertools.count() def make_counter(): i = 0 while True: i += 1 yield i nays = make_counter() print(nays.next()) | def make_counter return Fiber.new do i = 0 while true i += 1 Fiber.yield i end end end nays = make_counter puts nays.resume | |
decorator | def logcall(f): def wrapper(*a, **opts): print('calling ' + f.__name__) f(*a, **opts) print('called ' + f.__name__) return wrapper @logcall def square(x): return x * x | |||
invoke operator like function | import operator operator.mul(3, 7) a = ['foo', 'bar', 'baz'] operator.itemgetter(2)(a) | 3.*(7) a = ['foo', 'bar', 'baz'] a.[](2) | ||
execution control | ||||
javascript | php | python | ruby | |
if | if (0 == n) { alert("no hits"); } else if (1 == n) { alert("1 hit"); } else { alert(n + " hits"); } | if ( 0 == $n ) { echo "no hits\n"; } elseif ( 1 == $n 3ff0 ) { echo "one hit\n"; } else { echo "$n hits\n"; } | if 0 == n: print('no hits') elif 1 == n: print('one hit') else: print(str(n) + ' hits') | if n == 0 puts "no hits" elsif 1 == n puts "one hit" else puts "#{n} hits" end |
switch | switch (n) { case 0: alert("no hits\n"); break; case 1: alert("one hit\n"); break; default: alert(n + " hits\n"); } | switch ($n) { case 0: echo "no hits\n"; break; case 1: echo "one hit\n"; break; default: echo "$n hits\n"; } | none | case n when 0 puts "no hits" when 1 puts "one hit" else puts "#{n} hits" end |
while | while (i < 100) { i += 1; } | while ( $i < 100 ) { $i++; } | while i < 100: i += 1 | while i < 100 do i += 1 end |
for | for (var i = 0; i < 10; i++) { alert(i); } | for ($i = 1; $i <= 10; $i++) { echo "$i\n"; } | none | none |
break | break | break | break | break |
continue | continue | continue | continue | next |
statement modifiers | none | none | none | puts "positive" if i > 0 puts "nonzero" unless i == 0 |
exceptions | ||||
javascript | php | python | ruby | |
base exception | Any value can be thrown. | Exception | BaseException User-defined exceptions should subclassException. In Python 2 old-style classes can be thrown. | Exception User-defined exceptions should subclassStandardError. |
predefined exceptions | Error EvalError RangeError ReferenceError SyntaxError TypeError URIError | Exception LogicException BadFunctionCallException BadMethodCallException DomainException InvalidArgumentException LengthException OutOfRangeException RuntimeException OutOfBoundsException OverflowException RangeException UnderflowException UnexpectedValueException | BaseException SystemExit KeyboardInterrupt GeneratorExit Exception StopIteration StandardError BufferError ArithmeticError FloatingPointError OverflowError ZeroDivisionError AssertionError AttributeError EnvironmentError EOFError ImportError LookupError IndexError KeyError MemoryError NameError ReferenceError RuntimeError NotImplementedError SyntaxError SystemError TypeError ValueError UnicodeError Python 3 has a different tree | Exception NoMemoryError ScriptError LoadError NotImplementedError SyntaxError SignalException StandardError ArgumentError IOError EOFError IndexError LocalJumpError NameError RangeError RegexpError RuntimeError SecurityError SocketError SystemCallError Errno::* SystemStackError ThreadError TypeError ZeroDivisionError SystemExit fatal |
raise exception | throw new Error("bad arg"); | throw new Exception("bad arg"); | raise Exception('bad arg') | # raises RuntimeError raise "bad arg" |
catch-all handler | try { risky(); } catch (e) { alert("risky failed: " + e.message); } | try { risky(); } catch (Exception $e) { echo "risky failed: ", $e->getMessage(), "\n"; } | try: risky() except: print('risky failed') | # catches StandardError begin risky rescue print "risky failed: " puts $!.message end |
re-raise exception | try { throw new Error("bam!"); } catch (e) { alert("re-raising..."); throw e; } | try: raise Exception('bam!') except: print('re-raising...') raise | begin raise "bam!" rescue puts "re-raising…" raise end | |
global variable for last exception | none | none | last exception: sys.exc_info()[1] | last exception: $! backtrace array of exc.: $@ exit status of child: $? |
define exception | function Bam(msg) { this.message = msg; } Bam.prototype = new Error; | class Bam extends Exception { function __construct() { parent::__construct("bam!"); } } | class Bam(Exception): def __init__(self): super(Bam, self).__init__('bam!') | class Bam < Exception def initialize super("bam!") end end |
handle exception | try { throw new Bam("bam!"); } catch (e) { if (e instanceof Bam) { alert(e.message); } else { throw e; } } | try { throw new Bam; } catch (Bam $e) { echo $e->getMessage(), "\n"; } | try: raise Bam() except Bam as e: print(e) | begin raise Bam.new rescue Bam => e puts e.message end |
finally block | acquire_resource(); try { risky(); } finally { release_resource(); } | PHP 5.5: acquire_resource(); try { risky(); } finally { release_resource(); } | acquire_resource() try: risky() finally: release_resource() | acquire_resource begin risky ensure release_resource end |
concurrency | ||||
javascript | php | python | ruby | |
start thread | none | class sleep10(threading.Thread): def run(self): time.sleep(10) thr = sleep10() thr.start() | thr = Thread.new { sleep 10 } | |
wait on thread | thr.join() | thr.join | ||
____________________________________________ | ____________________________________________ | _____________________________________________ | _____________________________________________ |
file handles |
files |
directories |
processes and environment |
option parsing |
libraries and
相关文章推荐
- C,Ruby, Io, PHP, Python, Lua, Java, Perl, Applescript, TCL, ELisp, Javascript, OCaml, Ghostscript性能比较
- C,Ruby, Io, PHP, Python, Lua, Java, Perl, Applescript, TCL, ELisp, Javascript, OCaml, Ghostscript性能比较
- Perl/PHP/Python/Java/Ruby的拟人课堂讨论-比较各门编程语言的情况
- Perl,Python,Ruby,Javascript 四种脚本语言比较
- 比较Perl、PHP、Python、Java和Ruby 【转载】
- Perl/PHP/Python/Java/Ruby的拟人课堂讨论-比较各门编程语言的情况
- Perl,Python,Ruby,Javascript 四种脚本语言比较
- 脚本语言性能比较:Ruby,Io,PHP,Python,Lua,Java,Perl...
- 比较Perl、PHP、Python、Java和Ruby
- 脚本语言性能比较:Ruby,Io,PHP,Python,Lua,Java,Perl...
- 脚本语言性能比较:Ruby,Io,PHP,Python,Lua,Java,Perl...
- Perl、PHP、Python、Java和Ruby的比较
- 比较Perl、PHP、Python、Java和Ruby
- Ruby, Io, PHP, Python, Lua, Java, Perl, Applescript, TCL, ELisp, Javascript, OCaml, Ghostscript, and C Fractal Benchmark
- Perl、PHP、Python、Java和Ruby的比较
- 比较Perl、PHP、Python、Java和Ruby --转自乱炖--http://levi.cg.am/?p=711
- 强弱类型,动态静态语言比较(JAVA,C,C++,Python,Ruby,PHP,Perl)
- 编程开发(C/C++&Java&Python&JavaScript&Go&PHP&Ruby&Perl&R&Erlang)
- Perl、PHP、Python、Java和Ruby的比较
- Perl、PHP、Python、Java和Ruby的比较