PHP, Perl, Python, Ruby 语言特性的区别


Interpreted Languages: PHP, Perl, Python, Ruby (Sheet One)

a side-by-side reference sheet

sheet one: arithmetic and logic | strings | regexes | dates and time | arrays | dictionaries | functions | execution control
                 files | directories | processes and environment

sheet two: libraries and modules | objects | reflection | web | tests | debugging and profiling | java interop | contact

php (1995) perl (1987) python (1991) ruby (1995)
versions used
 
5.3 5.12; 5.14 2.7; 3.2 1.8; 1.9
implicit prologue none use strict; import os, re, sys none
show version
 
$ php --version $ perl --version $ python -V $ ruby --version
interpreter
 
$ php -f foo.php $ perl foo.pl $ python foo.py $ ruby foo.rb
repl
 
$ php $ perl -de 0 $ python $ irb
command line script $ php -r 'echo "hi\n";' $ perl -e 'print("hi\n")' $ python -c "print('hi')" $ ruby -e 'puts "hi"'
statement separator
 
;

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: \
block delimiters
 
{} {} offside rule {}
do end
assignment
 
$v = 1; $v = 1; assignments can be chained but otherwise don't return values:
v = 1
v = 1
parallel assignment
 
list($x, $y, $z) = array(1 ,2, 3);
# 3 is discarded:
list($x, $y) = array(1, 2, 3);
# $z set to NULL:
list($x, $y, $z) = array(1, 2);
($x, $y, $z) = (1, 2, 3);
# 3 is discarded:
($x, $y) = (1, 2, 3);
# $z set to undef:
($x, $y, $z) = (1, 2);
xyz = 1, 2, 3
# raises ValueError:
xy = 1, 2, 3
# raises ValueError:
xyz = 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
 
list($x, $y) = array($y, $x); ($x, $y) = ($y, $x); xy = y, x x, y = y, x
compound assignment operators: arithmetic, string, logical, bit += -= *= none /= %= **=
.= none
&= |= none
<<= >>= &= |= ^=
+= -= *= none /= %= **=
.= x=
&&= ||= ^=
<<= >>= &= |= ^=
# do not return values:
+= -= *= /= //= %= **=
+= *=
&= |= ^=
<<= >>= &= |= ^=
+= -= *= /= none %= **=
+= *=
&&= ||= ^=
<<= >>= &= |= ^=
increment and decrement
 
$x = 1;
$y = ++$x;
$z = --$y;
my $x = 1;
my $y = ++$x;
my $z = --$y;
none x = 1
# x and y not mutated:
y = x.succ
z = y.pred
local variable declarations
 
# in function body:
$v = NULL;
$a = array();
$d = array();
$x = 1;
list($y, $z) = array(2, 3);
my $v;
my (@a%d);
my $x = 1;
my ($y$z) = (2, 3);
# in function body:
v = None
ad = [], {}
x = 1
yz = 2, 3
v = nil
a, d = [], {}
x = 1
y, z = 2, 3
regions which define local scope top level:
  function or method body

nestable (with use clause):
  anonymous function body
top level:
  file

nestable:
  function body
  anonymous function body
  anonymous block
nestable (read only):
  function or method body
top level:
  file
  class block
  module block
  method body

nestable:
  anonymous function block
  anonymous block
global variable list($g1, $g2) = array(7, 8);
function swap_globals() {
  global $g1, $g2;
  list($g1, $g2) = array($g2, $g1);
}
our ($g1$g2) = (7, 8);
sub swap_globals {
  ($g1, $g2) = ($g2, $g1);
}
g1g2 = 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 declaration
 
define("PI", 3.14); use constant PI => 3.14; # uppercase identifiers
# constant by convention

PI = 3.14
# warning if capitalized
# identifier is reassigned

PI = 3.14
to-end-of-line comment
 
// comment
# comment
# comment # comment # comment
comment out multiple lines
 
/* comment line
another line */
=for
comment line
another line
=cut
use triple quote string literal:
'''comment line
another line'''
=begin
comment line
another line
=end
null
 
NULL # case insensitive undef None nil
null test
 
is_null($v)
! isset($v)
defined $v v == None
is None
v == nil
v.nil?
undefined variable access
 
NULL error under use strict; otherwise undef raises NameError raises NameError
undefined test
 
same as null test; no distinction between undefined variables and variables set to NULL same as null test; no distinction between undefined variables and variables set to undef not_defined = False
try: v
except NameError: not_defined = True
defined?(v)
arithmetic and logic
  php perl python ruby
true and false
 
TRUE FALSE # case insensitve "" True False true false
falsehoods
 
FALSE NULL 0 0.0 "" "0" array() undef 0 0.0 "" "0" () False None 0 0.0 '' [] {} false nil
logical operators
 
&& || !
lower precedence:
and or xor
&& || !
lower precedence:
and or xor not
and or not && || !
lower precedence:
and or not
conditional expression
 
$x > 0 ? $x : -$x $x > 0 ? $x : -$x if x > 0 else -x x > 0 ? x : -x
comparison operators
 
== != or <> > < >= <=
no conversion: === !==
numbers only: == != > < >= <=
strings: eq ne gt lt ge le
comparison operators are chainable:
== != > < >= <=
== != > < >= <=
three value comparison none 0 <=> 1
"do" cmp "re"
removed from Python 3:
cmp(0, 1)
cmp('do''re')
0 <=> 1
"do" <=> "re"
convert from string, to string
 
7 + "12"
73.9 + ".037"
"value: " . 8
7 + "12"
73.9 + ".037"
"value: " . 8
7 + int('12')
73.9 + float('.037')
'value: ' + str(8)
7 + "12".to_i
73.9 + ".037".to_f
"value: " + "8".to_s
arithmetic operators
 
+ - * / none % pow(b,e) + - * / none % ** + - * / // % ** + - * x.fdiv(y) / % **
integer division and divmod
 
(int) (13 / 5)
none
int ( 13 / 5 )
none
13 // 5
q, r = divmod(13, 5)
13 / 5
q, r = 13.divmod(5)
float division
 
13 / 5 13 / 5 float(13) / 5
# Python 3:
13 / 5
13.to_f / 5 or
13.fdiv(5)
arithmetic functions
 
sqrt exp log sin cos tan asin acos atan atan2 use Math::Trig qw(
  tan asin acos atan);

sqrt exp log sin cos tan asin acos atan atan2
from math import sqrt, exp, log, \
sin, cos, tan, asin, acos, atan, atan2
include Math

sqrt exp log sin cos tan asin acos atan atan2
arithmetic truncation
 
(int)$x
round($x)
ceil($x)
floor($x)
abs($x)
# cpan -i Number::Format
use Number::Format 'round';
use POSIX qw(ceil floor);

int($x)
round($x, 0)
ceil($x)
floor($x)
abs($x)
import math

int(x)
int(round(x))
math.ceil(x)
math.floor(x)
abs(x)
x.to_i
x.round
x.ceil
x.floor
x.abs
min and max
 
min(1,2,3)
max(1,2,3)
$a = array(1,2,3)
min($a)
max($a)
use List::Util qw(min max);

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
division by zero
 
returns FALSE with warning error raises ZeroDivisionError integer division raises ZeroDivisionError
float division returns Infinity
integer overflow
 
converted to float converted to float; use Math::BigInt to create arbitrary length integers becomes arbitrary length integer of type long becomes arbitrary length integer of type Bignum
float overflow
 
INF inf raises OverflowError Infinity
sqrt -2
 
NaN error unless use Math::Complex in effect # raises ValueError:
import math
math.sqrt(-2)

# returns complex float:
import cmath
cmath.sqrt(-2)
raises Errno::EDOM
rational numbers
 
none use Math::BigRat;

my $x = Math::BigRat->new("22/7");
$x->numerator();
$x->denominator();
from fractions import Fraction

x = Fraction(22,7)
x.numerator
x.denominator
require 'rational'

x = Rational(22,7)
x.numerator
x.denominator
complex numbers
 
none use Math::Complex;

my $z = 1 + 1.414 * i;
Re($z);
Im($z);
z = 1 + 1.414j
z.real
z.imag
require 'complex'

z = 1 + 1.414.im
z.real
z.imag
random integer, uniform float, normal float rand(0,99)
lcg_value()
none
int(rand() * 100)
rand()
none
import random

random.randint(0,99)
random.random()
random.gauss(0,1)
rand(100)
rand
none
set random seed, get and restore seed srand(17);

none
srand 17;

my $sd = srand;
srand($sd);
import random

random.seed(17)
sd = random.getstate()
random.setstate(sd)
srand(17)

sd = srand
srand(sd)
bit operators
 
<< >> & | ^ ~ << >> & | ^ ~ << >> & | ^ ~ << >> & | ^ ~
binary, octal, and hex literals none
052
0x2a
0b101010
052
0x2a
0b101010
052
0x2a
0b101010
052
0x2a
base conversion base_convert("42", 10, 7);
base_convert("60", 7, 10);
# cpan -i Math::BaseCalc
use Math::BaseCalc;

$c = new Math::BaseCalc(digits=>
  [0..6]);
$c->to_base(42);
$c->from_base("60");
none
int("60", 7)
42.to_s(7)
"60".to_i(7)
strings
  php perl python ruby
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 yes triple quote literals only yes
backslash escapes
 
double quoted:
\f \n \r \t \v \xhh \$ \" \ooo

single quoted:
\' \\
double quoted:
\a \b \cx \e \f \n \r \t \xhh \x{hhhh} \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

Ruby 1.9 double quoted:
\uhhhh \u{hhhhh}

single quoted:
\' \\
variable interpolation
 
$count = 3;
$item = "ball";
echo "$count ${item}s\n";
my $count = 3;
my $item = "ball";
print "$count ${item}s\n";
count = 3
item = 'ball'
print('{count} {item}s'.format(
  **locals()))
count = 3
item = "ball"
puts "#{count} #{item}s"
custom delimiters none my $s1 = q(lorem ipsum);
my $s2 = qq($s1 dolor sit amet);
none s1 = %q(lorem ipsum)
s2 = %Q(#{s1} dolor sit amet)
sprintf
 
$fmt = "lorem %s %d %f";
sprintf($fmt"ipsum", 13, 3.7);
my $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]
here document
 
$word = "amet";
$s = <<<EOF
lorem ipsum
dolor sit $word
EOF
;
$word = "amet";
$s = <<EOF;
lorem ipsum
dolor sit $word

EOF
none word = "amet"
s = <<EOF
lorem ipsum
dolor sit
 #{word}
EOF
concatenate
 
$s = "Hello, ";
$s2 = $s . "World!";
my $s = "Hello, ";
my $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
 
$hbar = str_repeat("-", 80); my $hbar = "-" x 80; hbar = '-' * 80 hbar = "-" * 80
split, in two, with delimiters, into characters explode(" ""do re mi fa")
preg_split('/\s+/'"do re mi fa", 2)
preg_split('/(\s+)/'"do re mi fa",
  NULLPREG_SPLIT_DELIM_CAPTURE);
str_split("abcd")
split(/\s+/"do re mi fa")
split(/\s+/"do re mi fa", 2)
split(/(\s+)/"do re mi fa");
split(//"abcd")
'do re mi fa'.split()
'do re mi fa'.split(None, 1)
re.split('(\s+)''do re mi fa')
list('abcd')
"do re mi fa".split
"do re mi fa".split(/\s+/, 2)
"do re mi fa".split(/(\s+)/)
"abcd".split("")
join
 
$a = array("do""re""mi""fa");
implode(" ", $a)
join(" "qw(do re mi fa)) ' '.join(['do''re''mi''fa']) %w(do re mi fa).join(' ')
case manipulation strtoupper("lorem")
strtolower("LOREM")
ucfirst("lorem")
uc("lorem")
lc("LOREM")
ucfirst("lorem")
'lorem'.upper()
'LOREM'.lower()
'lorem'.capitalize()
"lorem".upcase
"LOREM".downcase
"lorem".capitalize
strip
 
trim(" lorem ")
ltrim(" lorem")
rtrim("lorem ")
# cpan -i Text::Trim
use Text::Trim;

trim " lorem "
ltrim " lorem"
rtrim "lorem "
' lorem '.strip()
' lorem'.lstrip()
'lorem '.rstrip()
" lorem ".strip
" lorem".lstrip
"lorem ".rstrip
pad on right, on left
 
str_pad("lorem", 10)
str_pad("lorem", 10, " ",
  STR_PAD_LEFT)
sprintf("%-10s""lorem")
sprintf("%10s""lorem")
'lorem'.ljust(10)
'lorem'.rjust(10)
"lorem".ljust(10)
"lorem".rjust(10)
length
 
strlen("lorem") length("lorem") len('lorem') "lorem".length
"lorem".size
index of substring
 
strpos("do re re""re")
strrpos("do re re""re")
return FALSE if not found
index("lorem ipsum""ipsum")
rindex("do re re""re")
return -1 if not found
'do re re'.index('re')
'do re re'.rindex('re')
raise ValueError if not found
"do re re".index("re")
"do re re".rindex("re")
return nil if not found
extract substring
 
substr("lorem ipsum", 6, 5) substr("lorem ipsum", 6, 5) 'lorem ipsum'[6:11] "lorem ipsum"[6, 5]
extract character syntax error to use index notation directly on string literal:
$s = "lorem ipsum";
$s[6];
can't use index notation with strings:
substr("lorem ipsum", 6, 1)
'lorem ipsum'[6] "lorem ipsum"[6]
chr and ord
 
chr(65)
ord("A")
chr(65)
ord("A")
chr(65)
ord('A')
65.chr
"A"[0]   Ruby 1.9: "A".ord
character translation
 
$ins = implode(range("a""z"));
$outs = substr($ins, 13, 13) . substr($ins, 0, 13);
strtr("hello", $ins, $outs)
$s = "hello";
$s =~ tr/a-z/n-za-m/;
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")
regular expresions
  php perl python ruby
literal, custom delimited literal '/lorem|ipsum/'
'(/etc/hosts)'
/lorem|ipsum/
qr(/etc/hosts)
re.compile('lorem|ipsum')
none
/lorem|ipsum/
%r(/etc/hosts)
character class abbreviations and anchors char class abbrevs:
. \d \D \h \H \s \S \v \V \w \W

anchors: ^ $ \A \b \B \z \Z
char class abbrevs:
. \d \D \h \H \s \S \v \V \w \W

anchors: ^ $ \A \b \B \z \Z
char class abbrevs:
. \d \D \s \S \w \W

anchors: ^ $ \A \b \B \Z
char class abbrevs:
. \d \D \h \H \s \S \w \W

anchors: ^ $ \A \b \B \z \Z
match test
 
if (preg_match('/1999/', $s)) {
  echo "party!\n";
}
if ($s =~ /1999/) {
  print "party!\n";
}
if re.search('1999', s):
  print('party!')
if /1999/.match(s)
  puts "party!"
end
case insensitive match test preg_match('/lorem/i'"Lorem") "Lorem" =~ /lorem/i re.search('lorem''Lorem', re.I) /lorem/i.match("Lorem")
modifiers
 
e i m s x i m s p x re.I re.M re.S re.X i o m x
substitution
 
$s = "do re mi mi mi";
$s = preg_replace('/mi/'"ma", $s);
my $s = "do re mi mi mi";
$s =~ s/mi/ma/g;
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
 
none if ($s =~ /\d{4}/p) {
  $match = ${^MATCH};
  $prematch = ${^PREMATCH};
  $postmatch = ${^POSTMATCH};
}
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
 
$s = "2010-06-03";
$rx = '/(\d{4})-(\d{2})-(\d{2})/';
preg_match($rx, $s, $m);
list($_, $yr, $mo, $dy) = $m;
$rx = qr/(\d{4})-(\d{2})-(\d{2})/;
"2010-06-03" =~ $rx;
($yr, $mo, $dy) = ($1, $2, $3);
rx = '(\d{4})-(\d{2})-(\d{2})'
m = re.search(rx, '2010-06-03')
yrmody = m.groups()
rx = /(\d{4})-(\d{2})-(\d{2})/
m = rx.match("2010-06-03")
yr, mo, dy = m[1..3]
scan
 
$s = "dolor sit amet";
preg_match_all('/\w+/', $s, $m);
$a = $m[0];
my $s = "dolor sit amet";
@a = $s =~ m/\w+/g;
s = 'dolor sit amet'
a = re.findall('\w+', s)
a = "dolor sit amet".scan(/\w+/)
backreference in match and substitution preg_match('/(\w+) \1/'"do do")

$s = "do re";
$rx = '/(\w+) (\w+)/';
$s = preg_replace($rx'\2 \1', $s);
"do do" =~ /(\w+) \1/

my $s = "do re";
$s =~ s/(\w+) (\w+)/$2 $1/;
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 '/\(([^()]*|($R))\)/' /\(([^()]*|(?R))\)/ none Ruby 1.9:
/(?

\(([^()]*|\g

)*\))/

dates and time
  php perl python ruby
date/time type
 
DateTime Time::Piece if use Time::Piece in effect, otherwise tm array datetime.datetime Time
current date/time $t = new DateTime("now");
$utc_tmz = new DateTimeZone("UTC");
$utc = new DateTime("now", $utc_tmz);
use Time::Piece;

my $t = localtime(time);
my $utc = gmtime(time);
import datetime

t = datetime.datetime.now()
utc = datetime.datetime.utcnow()
t = Time.now
utc = Time.now.utc
to unix epoch, from unix epoch $epoch = $t->getTimestamp();
$t2 = new DateTime();
$t2->setTimestamp(1304442000);
use Time::Local;
use Time::Piece;

my $epoch = timelocal($t);
my $t2 = localtime(1304442000);
from datetime import datetime as dt

epoch = int(t.strftime("%s"))
t2 = dt.fromtimestamp(1304442000)
epoch = t.to_i
t2 = Time.at(1304442000)
current unix epoch $epoch = time(); $epoch = time; import datetime

t = datetime.datetime.now()
epoch = int(t.strftime("%s"))
epoch = Time.now.to_i
strftime strftime("%Y-%m-%d %H:%M:%S", $epoch);
date("Y-m-d H:i:s", $epoch);
$t->format("Y-m-d H:i:s");
use Time::Piece;

$t = localtime(time);
$fmt = "%Y-%m-%d %H:%M:%S";
print $t->strftime($fmt);
t.strftime('%Y-%m-%d %H:%M:%S') t.strftime("%Y-%m-%d %H:%M:%S")
default format example no default string representation Tue Aug 23 19:35:19 2011 2011-08-23 19:35:59.411135 2011-08-23 17:44:53 -0700
strptime $fmt = "Y-m-d H:i:s";
$s = "2011-05-03 10:00:00";
$t = DateTime::createFromFormat($fmt,
  $s);
use Time::Local;
use Time::Piece;

$s = "2011-05-03 10:00:00";
$fmt = "%Y-%m-%d %H:%M:%S";
$t = Time::Piece->strptime($s,$fmt);
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 = Date.strptime(s, fmt).to_time
parse date w/o format $epoch = strtotime("July 7, 1999"); # cpan -i Date::Parse
use Date::Parse;

$epoch = str2time("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
result of date subtraction 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);
Time::Seconds object if use Time::Piece in effect; not meaningful to subtract tm arrays datetime.timedelta object Float containing time difference in seconds
add time duration $now = new DateTime("now");
$now->add(new DateInterval("PT10M3S");
use Time::Seconds;

$now = localtime(time);
$now += 10 * ONE_MINUTE() + 3;
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 timezone DateTime objects can be instantiated without specifying the timezone if a default is set:
$s = "America/Los_Angeles";
date_default_timezone_set($s);
Time::Piece has local timezone if created with localtimeand UTC timezone if created with gmtime; tm arrays have no timezone or offset info a datetime object has no timezone information unless atzinfo object is provided when it is created if no timezone is specified the local timezone is used
timezone name; offset from UTC; is daylight savings? $tmz = date_timezone_get($t);
timezone_name_get($tmz);
date_offset_get($t) / 3600;
$t->format("I");
# cpan -i DateTime
use DateTime;
use DateTime::TimeZone;

$dt = DateTime->now();
$tz = DateTime::TimeZone->new(
  name=>"local");

$tz->name;
$tz->offset_for_datetime($dt) /
  3600;
$tz->is_dst_for_datetime($dt);
import time

tm = time.localtime()
  
time.tzname[tm.tm_isdst]
(time.timezone / -3600) + tm.tm_isdst
tm.tm_isdst
t.zone
t.utc_offset / 3600
t.dst?
microseconds list($frac, $sec) = explode(" ",
  microtime());
$usec = $frac * 1000 * 1000;
use Time::HiRes qw(gettimeofday);

($sec, $usec) = gettimeofday;
t.microsecond t.usec
sleep a float argument will be truncated to an integer:
sleep(1);
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; use stream_set_timeout to limit time spent reading from a stream opened with fopen or fsockopen eval {
  $SIG{ALRM}= sub {die "timeout!";};
  alarm 5;
  sleep 10;
};
alarm 0;
import signal, time

class Timeout(Exception): pass

def timeout_handler(signo, fm):
  raise Timeout()

signal.signal(signal.SIGALRM,
  timeout_handler)

try:
  signal.alarm(5)
  time.sleep(10)
except Timeout:
  pass
signal.alarm(0)
require 'timeout'

begin
  Timeout.timeout(5) do
    sleep(10)
  end
rescue Timeout::Error
end
arrays
  php perl python ruby
literal
 
$a = array(1, 2, 3, 4); @a = (1, 2, 3, 4); a = [1, 2, 3, 4] a = [1, 2, 3, 4]
quote words
 
none @a = qw(do re mi); none a = %w(do re mi)
size
 
count($a) $#a + 1 or
scalar(@a)
len(a) a.size
a.length # same as size
empty test
 
!$a !@a not a NoMethodError if a is nil:
a.empty?
lookup
 
$a[0] $a[0] a[0] a[0]
update
 
$a[0] = "lorem"; $a[0] = "lorem"; a[0] = 'lorem' a[0] = "lorem"
out-of-bounds behavior $a = array();
evaluates as NULL:
$a[10];
increases array size to one:
$a[10] = "lorem";
@a = ();
evaluates as undef:
$a[10];
increases array size to 11:
$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"
index of array element $a = array("x""y""z""w");
$i = array_search("y", $a);
use List::Util 'first';

@a = qw(x y z w);
$i = first {$a[$_] eq "y"} (0..$#a);
a = ['x''y''z''w']
i = a.index('y')
a = %w(x y z w)
i = a.index("y")
slice by endpoints, by length
 
select 3rd and 4th elements:
none
array_slice($a, 2, 2)
select 3rd and 4th elements:
@a[2..3]
splice(@a, 2, 2)
select 3rd and 4th elements:
a[2:4]
none
select 3rd and 4th elements:
a[2..3]
a[2, 2]
slice to end
 
array_slice($a, 1) @a[1..$#a] a[1:] a[1..-1]
manipulate back
 
$a = array(6,7,8);
array_push($a, 9);
$a[] = 9; # same as array_push
array_pop($a);
@a = (6,7,8);
push @a, 9;
pop @a;
a = [6,7,8]
a.append(9)
a.pop()
a = [6,7,8]
a.push(9)
<< 9 # same as push
a.pop
manipulate front
 
$a = array(6,7,8);
array_unshift($a, 5);
array_shift($a);
@a = (6,7,8);
unshift @a, 5;
shift @a;
a = [6,7,8]
a.insert(0,5)
a.pop(0)
a = [6,7,8]
a.unshift(5)
a.shift
concatenate $a = array(1,2,3);
$a2 = array_merge($a,array(4,5,6));
$a = array_merge($a,array(4,5,6));
@a = (1,2,3);
@a2 = (@a,(4,5,6));
push @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   @a = (undefx 10; a = [None] * 10
a = [None for i in range(0, 10)]
a = [nil] * 10
a = Array.new(10, nil)
address copy, shallow copy, deep copy $a = array(1,2,array(3,4));
$a2 =& $a;
none
$a4 = $a;
use Storable 'dclone'

my @a = (1,2,[3,4]);
my $a2 = \@a;
my @a3 = @a;
my @a4 = @{dclone(\@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))
arrays as function arguments parameter contains deep copy each element passed as separate argument; use reference to pass array as single argument parameter contains address copy parameter contains address copy
iteration
 
foreach (array(1,2,3) as $i) {
  echo "$i\n";
}
for $i (1, 2, 3) { print "$i\n" } for i in [1,2,3]:
  print(i)
[1,2,3].each { |i| puts i }
indexed iteration $a = array("do""re""mi" "fa");
foreach ($a as $i => $s) {
  echo "$s at index $i\n";
}
none; use range iteration from 0 to $#a and use index to look up value in the loop body 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 for $i (1..1_000_000) {
  code
}
range replaces xrange in Python 3:
for i in xrange(1, 1000001):
  code
(1..1_000_000).each do |i|
  code
end
instantiate range as array $a = range(1, 10); @a = 1..10; a = range(1, 11)
Python 3:
a = list(range(1, 11))
a = (1..10).to_a
reverse $a = array(1,2,3);
array_reverse($a);
$a = array_reverse($a);
@a = (1,2,3);
reverse @a;
@a = reverse @a;
a = [1,2,3]
a[::-1]
a.reverse()
a = [1,2,3]
a.reverse
a.reverse!
sort $a = array("b""A""a""B");
none
sort($a);
none, but usort sorts in place
@a = qw(b A a B);
sort @a;
@a = sort @a;
sort { lc($a) cmp lc($b) } @a;
a = ['b''A''a''B']
sorted(a)
a.sort()
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 $a = array(1,2,2,3);
$a2 = array_unique($a);
$a = array_unique($a);
use List::MoreUtils 'uniq';

my @a = (1,2,2,3);
my @a2 = uniq @a;
@a = uniq @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
 
in_array(7, $a) 7 ~~ @a in a a.include?(7)
intersection
 
$a = array(1,2);
$b = array(2,3,4)
array_intersect($a, $b)
  {1,2} & {2,3,4} [1,2] & [2,3,4]
union
 
$a1 = array(1,2);
$a2 = array(2,3,4);
array_unique(array_merge($a1, $a2))
  {1,2} | {2,3,4} [1,2] | [2,3,4]
relative complement, symmetric difference $a1 = array(1,2,3);
$a2 = array(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
 
array_map(function ($x) {
    return $x*$x;
  }, array(1,2,3))
map { $_ * $_ } (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
 
array_filter(array(1,2,3),
  function ($x) {
    return $x>1;
  })
grep { $_ > 1 } (1,2,3) 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
 
array_reduce(array(1,2,3),
  function($x,$y) {
    return $x+$y;
  }, 0)
use List::Util 'reduce';

reduce { $x + $y } 0, (1,2,3)
# 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
 
use array_filter # cpan -i List::MoreUtils
use List::MoreUtils qw(all any);

all { $_ % 2 == 0 } (1,2,3,4)
any { $_ % 2 == 0 } (1,2,3,4)
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 $a = array(1, 2, 3, 4);
shuffle($a);
array_rand($a, 2)
use List::Util 'shuffle';

@a = (1, 2, 3, 4);
shuffle(@a);
none
from random import shuffle, sample

a = [1, 2, 3, 4]
shuffle(a)
sample(a, 2)
[1, 2, 3, 4].shuffle
Ruby 1.9:
[1, 2, 3, 4].sample(2)
zip
 
# array of 3 pairs:
$a = array_map(NULL,
  array(1, 2, 3),
  array("a""b""c"));
# cpan -i List::MoreUtils
use List::MoreUtils 'zip';

@nums = (1, 2, 3);
@lets = qw(a b c);
# flat array of 6 elements:
@a = zip @nums@lets;
# array of 3 pairs:
a = zip([1,2,3], ['a''b''c'])
# array of 3 pairs:
a = [1,2,3].zip(["a""b""c"])
dictionaries
  php perl python ruby
literal
 
$d = array("t" => 1, "f" => 0); %d = ( t => 1, f => 0 ); d = { 't':1, 'f':0 } d = { "t" => 1, "f" => 0 }
size
 
count($d) scalar(keys %d) len(d) d.size
d.length # same as size
lookup
 
$d["t"] $d{"t"} d['t'] d["t"]
out-of-bounds behavior
 
$d = array();
evaluates as NULL:
$d["lorem"];
adds key/value pair:
$d["lorem"] = "ipsum";
%d = ();
evaluates as undef:
$d{"lorem"};
adds key/value pair:
$d{"lorem"} = "ipsum";
d = {}
raises KeyError:
d['lorem']
adds key/value pair:
d['lorem'] = 'ipsum'
d = {}
evaluates as nil:
d["lorem"]
adds key/value pair:
d["lorem"] = "ipsum"
is key present
 
array_key_exists("y", $d); exists $d{"y"} 'y' in d d.has_key?("y")
delete entry $d = array(1 => "t", 0 => "f");
unset($d[1]);
%d = ( 1 => "t", 0 => "f" );
delete $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   @a = (1,"a",2,"b",3,"c");
%d = @a;
a = [[1,'a'], [2,'b'], [3,'c']]
d = dict(a)

a = [1,'a',2,'b',3,'c']
d = dict(zip(a[::2], a[1::2]))
a = [[1,"a"], [2,"b"], [3,"c"]]
d = Hash[a]

a = [1,"a",2,"b",3,"c"]
d = Hash[*a]
merge $d1 = array("a"=>1, "b"=>2);
$d2 = array("b"=>3, "c"=>4);
$d1 = array_merge($d1, $d2);
%d1 = (a=>1, b=>2);
%d2 = (b=>3, c=>4);
%d1 = (%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 $to_num = array("t"=>1, "f"=>0);
$to_let = array_flip($to_num);
%to_num = (t=>1, f=>0);
%to_let = reverse %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
iteration
 
foreach ($d as $k => $v ) {
  code
}
while ( ($k, $v) = each %d ) {
  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 array_keys($d)
array_values($d)
keys %d
values %d
d.keys()
d.values()

Python 3:
list(d.keys())
list(d.values())
d.keys
d.values
default value, computed value $counts = array();
$counts['foo'] += 1;

extend ArrayObject for computed values and defaults other than zero or empty string.
my %counts;
$counts{'foo'} += 1

define a tied hash 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
  php perl python ruby
function declaration
 
function add($a, $b) {
  return $a + $b;
}
sub add { $_[0] + $_[1] }

sub add {
  my ($a$b) = @_;
  $a + $b;
}
def add(a, b):
  return a+b
def add(a, b)
  a+b
end

parens are optional and customarily omitted when defining functions with no parameters
function invocation add(1, 2);

function names are case insensitive:
ADD(1, 2);
add(1, 2);

parens are optional:
add 1, 2;
add(1, 2) add(1, 2)

parens are optional:
add 1, 2
missing argument behavior
 
set to NULL with warning set to undef raises TypeError raises ArgumentError
default value
 
function my_log($x, $base=10) {
  return log($x)/log($base);
}

my_log(42);
my_log(42, M_E);
sub my_log {
  my $x = shift;
  my $base = shift // 10;

  log($x)/log($base);
}

my_log(42);
my_log(42, exp(1));
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)
variable number of arguments function foo() {
  $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";
  }
}
sub foo {
  if ( @_ >= 1 ) {
    print "first: $_[0]\n";
  }
  if ( @_ >= 2 ) {
    print "last: $_[-1]\n";
  }
}
def foo(*a):
  if len(a) >= 1:
    print('first: ' + str(a[0]))
  if len(a) >= 2:
    print('last: ' + str(a[-1]))
def foo(*a)
  if a.size >= 1
    puts "first: #{a[0]}"
  end
  if a.size >= 2
    puts "last: #{a[-1]}"
  end
end
named parameters
 
none none def fequal(x, y, **opts):
  eps = opts.get('eps'or 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)
pass number or string by reference
 
function foo(&$x, &$y) {
  $x += 1;
  $y .= "ly";
}

$n = 7;
$s = "hard";
foo($n, $s);
sub foo {
  $_[0] += 1;
  $_[1] .= "ly";
}

my $n = 7;
my $s = "hard";
foo($n, $s);
not possible not possible
pass array or dictionary by reference
 
function foo(&$x, &$y) {
  $x[2] = 5;
  $y["f"] = -1;
}

$a = array(1,2,3);
$d = array("t"=>1,"f"=>0);
foo($a, $d);
sub foo {
  $_[0][2] = 5;
  $_[1]{"f"} = -1;
}

my @a = (1,2,3);
my %d = ("t"=> 1, "f" => 0);
foo(\@a, \%d);
def foo(x, y):
  x[2] = 5
  y['f'] = -1

a = [1,2,3]
d = {'t':1, 'f':0}
foo(a, d)
def foo(x, y)
  x[2] = 5
  y["f"] = -1
end

a = [1,2,3]
d = {"t"=> 1, "f" => 0 }
foo(a, d)
return value
 
return arg or NULL return arg or last expression evaluated return arg or None return arg or last expression evaluated
multiple return values
 
function first_and_second(&$a) {
  return array($a[0], $a[1]);
}
$a = array(1,2,3);
list($x, $y) =
  first_and_second($a);
sub first_and_second {
  return ($_[0], $_[1]);
}
@a = (1,2,3);
($x, $y) = first_and_second(@a);
def first_and_second(a):
  return a[0], a[1]

xy = 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])
lambda declaration
 
$sqr = function ($x) {
  return $x * $x;
};
$sqr = sub { $_[0] * $_[0] } body must be an expression:
sqr = lambda x: x * x
sqr = lambda { |x| x * x }
lambda invocation $sqr(2) $sqr->(2) sqr(2) sqr.call(2) or
sqr[2]
function reference $func = "add"; my $func = \&add; func = add func = lambda {|*args| add(*args)}
function with private state function counter() {
  static $i = 0;
  return ++$i;
}

echo counter();
use feature state;

sub counter {
  state $i = 0;
  ++$i;
}

print counter() . "\n";
# state not private:
def counter():
  counter.i += 1
  return counter.i

counter.i = 0
print(counter())
none
closure function make_counter() {
  $i = 0;
  return function () use (&$i) {
    return ++$i;
  };
}
$nays = make_counter();
echo $nays();
sub make_counter {
  my $i = 0;
  return sub { ++$i };
}
my $nays = make_counter;
print $nays->() . "\n";
# 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 none none def make_counter():
  i = 0
  while True:
    i += 1
    yield i

nays = make_counter()
print(nays.next())
# Ruby 1.9:
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
execution control
  php perl python ruby
if
 
if ( 0 == $n ) {
  echo "no hits\n";
elseif ( 1 == $n ) {
  echo "one hit\n";
else {
  echo "$n hits\n";
}
if ( 0 == $n ) {
  print "no hits\n"
elsif ( 1 == $n ) {
  print "one hit\n"
else {
  print "$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:
  echo "no hits\n";
  break;
case 1:
  echo "one hit\n";
  break;
default:
  echo "$n hits\n";
}
use feature 'switch';

given ($n) {
  when (0) { print "no hits\n"; }
  when (1) { print "one hit\n"; }
  default { print "$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++; } while ( $i < 100 ) { $i++ } while i < 100:
  i += 1
while i < 100 do
  i += 1
end
c-style for
 
for ($i = 1; $i <= 10; $i++) {
  echo "$i\n";
}
for ( $i=0; $i <= 10; $i++ ) {
  print "$i\n";
}
none none
break, continue, redo
 
break continue none last next redo break continue none break next redo
control structure keywords case default do else elseif for foreach goto if switch while do else elsif for foreach goto if unless until while elif else for if while case do else elsif end for loop when while unless until
what do does starts body of a do-while loop, a loop which checks the condition after the body is executed executes following block and returns value of last statement executed raises NameError unless a value was assigned to it starts an anonymous block. Also starts the body of aloop, while, or until loop
statement modifiers
 
none print "positive\n" if $i > 0;
print "nonzero\n" unless $i == 0;
none puts "positive" if i > 0
puts "nonzero" unless i == 0
raise exception
 
throw new Exception("bad arg"); die "bad arg"; raise Exception('bad arg') # raises RuntimeError
raise "bad arg"
catch exception
 
try {
  risky();
catch (Exception $e) {
  echo "risky failed: ",
    $e->getMessage(), "\n";
}
eval { risky };
if ($@) {
  print "risky failed: $@\n";
}
try:
  risky()
except:
  print('risky failed')
# catches StandardError
begin
  risky
rescue
  print "risky failed: "
  puts $!.message
end
global variable for last exception none $EVAL_ERROR: $@
$OS_ERROR: $!
$CHILD_ERROR: $?
last exception: sys.exc_info()[1] last exception: $!
backtrace array of exc.: $@
exit status of child: $?
define exception class Bam extends Exception {
  function __construct() {
    parent::__construct("bam!");
  }
}
none class Bam(Exception):
  def __init__(self):
    super(Bam, self).__init__('bam!')
class Bam < Exception
  def initialize
    super("bam!")
  end
end
catch exception by type try {
  throw new Bam;
catch (Bam $e) {
  echo $e->getMessage(), "\n";
}
none try:
  raise Bam()
except Bam as e:
  print(e)
begin
  raise Bam.new
rescue Bam => e
  puts e.message
end
finally/ensure
 
none none acquire_resource()
try:
  risky()
finally:
  release_resource()
acquire_resource
begin
  risky
ensure
  release_resource
end
start thread
 
none use threads;

$func = sub { sleep 10 };
$thr = threads->new($func);
class sleep10(threading.Thread):
  def run(self):
    time.sleep(10)

thr = sleep10()
thr.start()
thr = Thread.new { sleep 10 }
wait on thread
 
none $thr->join; thr.join() thr.join
files
  php perl python ruby
print to standard output
 
echo "Hello, World!\n"; print "Hello, World!\n"; print('Hello, World!') puts "Hello, World!"
read from standard input $line = fgets(STDIN); $line = ; line = sys.stdin.readline() line = gets
standard file handles
 
only set by CLI; not set when reading script from standard input:
STDIN STDOUT STDERR
STDIN STDOUT STDERR sys.stdin sys.stdout sys.stderr $stdin $stdout $stderr
open file
 
$f = fopen("/etc/hosts""r"); open my $f"/etc/hosts"or
open FILE, "/etc/hosts";
f = open('/etc/hosts') f = File.open("/etc/hosts"or
File.open("/etc/hosts") { |f|
open file for writing
 
$f = fopen("/tmp/php_test""w"); open my $f">/tmp/perl_test"or
open FILE, ">/tmp/perl_test";
f = open('/tmp/test''w') f = File.open('/tmp/test''w'or
File.open('/tmp/test''w') { |f|
close file
 
fclose($f); close $f; or
close FILE;
f.close() f.close
read line
 
$line = fgets($f); $line = <$f>; or
$line = ;
f.readline() f.gets
iterate over file by line
 
while (!feof($f)) {
  $line = fgets($f);
while ($line = <$f>) { for line in f: f.each do |line|
chomp
 
chop($line); chomp $line; line = line.rstrip('\r\n') line.chomp!
read entire file into array or string $a = file("/etc/hosts");
$s = file_get_contents("/etc/hosts");
@a = <$f>;
$s = do { local $/; <$f> };
a = f.readlines()
s = f.read()
a = f.lines.to_a
s = f.read
write to file
 
fwrite($f"lorem ipsum"); print $f "lorem ipsum"; f.write('lorem ipsum') f.write("lorem ipsum")
flush file handle
 
note that CLI output isn't buffered
fflush($f);
use IO::Handle;

$f->flush();
f.flush() f.flush
file test, regular file test
 
file_exists("/etc/hosts")
is_file("/etc/hosts")
-e "/etc/hosts"
-f "/etc/hosts"
os.path.exists('/etc/hosts')
os.path.isfile('/etc/hosts')
File.exists?("/etc/hosts")
File.file?("/etc/hosts")
copy file, remove file, rename file copy("/tmp/foo""/tmp/bar");
unlink("/tmp/foo");
rename("/tmp/bar""/tmp/foo");
use File::Copy;

copy("/tmp/foo""/tmp/bar");
unlink "/tmp/foo";
move("/tmp/bar""/tmp/foo");
import shutil

shutil.copy('/tmp/foo''/tmp/bar')
os.remove('/tmp/foo')
shutil.move('/tmp/bar''/tmp/foo')
require 'fileutils'

FileUtils.cp("/tmp/foo""/tmp/bar")
FileUtils.rm("/tmp/foo")
FileUtils.mv("/tmp/bar""/tmp/foo")
set file permissions chmod("/tmp/foo", 0755); chmod 0755, "/tmp/foo"; os.chmod('/tmp/foo', 0755) File.chmod(0755, "/tmp/foo")
temporary file $tmp = tempnam(sys_get_temp_dir(),
  "foo");
$f = fopen($tmp"w");
fwrite($f"lorem ipsum\n");
fclose($f);

echo "tmp file: $tmp\n";
use File::Temp;

$f = File::Temp->new();
print $f "lorem ipsum\n";
close $f;

print "tmp file: ";
print $f->filename . "\n";
import tempfile

f = tempfile.NamedTemporaryFile(
  prefix='foo')
f.write('lorem ipsum\n')
f.close()

print("tmp file: %s" % f.name)
require 'tempfile'

f = Tempfile.new('foo')
f.puts "lorem ipsum"
f.close

puts "tmp file: #{f.path}"
in memory file $meg = 1024 * 1024;
$mem = "php://temp/maxmemory:$meg";
$f = fopen($mem"r+");
fputs($f"lorem ipsum");
rewind($f);
$s = fread($f, $meg);
my ($f$s);
open($f">", \$s);
print $f "lorem ipsum\n";
$s;
from StringIOimport StringIO

f = StringIO()
f.write('lorem ipsum\n')
s = f.getvalue()

Python 3 moved StringIO to the io module
require 'stringio'

f = StringIO.new
f.puts("lorem ipsum")
f.rewind
s = f.read
directories
  php perl python ruby
build pathname "/etc" . DIRECTORY_SEPARATOR . "hosts" use File::Spec;

File::Spec->catfile("/etc""hosts")
os.path.join('/etc''hosts') File.join("/etc""hosts")
dirname and basename dirname("/etc/hosts")
basename("/etc/hosts")
use File::Basename;

print dirname("/etc/hosts");
print basename("/etc/hosts");
os.path.dirname('/etc/hosts')
os.path.basename('/etc/hosts')
File.dirname("/etc/hosts")
File.basename("/etc/hosts")
absolute pathname realpath("..") use Cwd;

Cwd::abs_path("..")
os.path.abspath('..') File.expand_path("..")
iterate over directory by file if ($dir = opendir("/etc")) {
  while ($file = readdir($dir)) {
    echo "$file\n";
  }
  closedir($dir);
}
use File::Basename;

while (  ) {
   print basename($_) . "\n";
}
for filename in os.listdir('/etc'):
  print(filename)
Dir.open("/etc").each do |file|
  puts file
end
make directory mkdir("/tmp/foo/bar", 0755, TRUE); use File::Path 'make_path';

make_path "/tmp/foo/bar";
dirname = '/tmp/foo/bar'
if not os.path.isdir(dirname):
  os.makedirs(dirname)
require 'fileutils'

FileUtils.mkdir_p("/tmp/foo/bar")
recursive copy none # cpan -i File::Copy::Recursive
use File::Copy::Recursive 'dircopy';

dircopy "/tmp/foodir",
  "/tmp/bardir";
import shutil

shutil.copytree('/tmp/foodir',
  '/tmp/bardir')
require 'fileutils'

FileUtils.cp_r("/tmp/foodir",
  "/tmp/bardir")
remove empty directory rmdir("/tmp/foodir"); rmdir "/tmp/foodir"; os.rmdir('/tmp/foodir') File.rmdir("/tmp/foodir")
remove directory and contents none use File::Path 'remove_tree';

remove_tree "/tmp/foodir";
import shutil

shutil.rmtree('/tmp/foodir')
require 'fileutils'

FileUtils.rm_rf("/tmp/foodir")
directory test
 
is_dir("/tmp") -d "/tmp" os.path.isdir('/tmp') File.directory?("/tmp")
processes and environment
  php perl python ruby
command line args, script name
 
count($argv)
$argv[0] $argv[1] etc
$_SERVER["SCRIPT_NAME"]
scalar(@ARGV)
$ARGV[0] $ARGV[1] etc
$0
len(sys.argv)-1
sys.argv[1] sys.argv[2] etc
sys.argv[0]
ARGV.size
ARGV[0] ARGV[1] etc
$0
getopt $opts = getopt("f:h",
  array("file:""help"));

if ( array_key_exists("h", $opts||
  array_key_exists("help", $opts) ) {

  $script = $_SERVER["SCRIPT_NAME"];
  echo "usage: $script -f SRC -h\n";
  exit -1;
}

$src = $opts["f"] ? $opts["f"] :
  $opts["file"];
use Getopt::Long;

my ($src$help);

sub usage {
  print "usage: $0 --f SRC\n";
  exit -1;
}

GetOptions("file=s" => \$src,
  "help" => \$help);

usage if $help;
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--file''-f',
  dest='file')

args = parser.parse_args()
src = args.file
require 'getoptlong'

opts = GetoptLong.new(
  ['--help''-h',
   GetoptLong::NO_ARGUMENT],
  ['--file''-f',
   GetoptLong::REQUIRED_ARGUMENT]
)

opts.each do |opt, arg|
  case opt
  when '--file'
    src = arg
  when '--help'
    puts "usage: #{$0} -f SRC"
    exit -1
  end
end
get and set environment variable
 
getenv("HOME")

putenv("PATH=/bin");
$ENV{"HOME"}

$ENV{"PATH") = "/bin";
os.getenv('HOME')

os.environ['PATH'] = '/bin'
ENV["HOME"]

ENV["PATH"] = "/bin"
exit
 
exit 0; exit 0; sys.exit(0) exit(0)
set signal handller
 
  $SIG{INT} = sub {
  die "exiting…\n";
};
import signal

def handler(signo, frame):
  print('exiting…')
  exit -1
signal.signal(signal.SIGINT, handler)
Signal.trap("INT",
  lambda do |signo|
    puts "exiting…"
    exit
  end
)
executable test is_executable("/bin/ls") -x "/bin/ls" os.access('/bin/ls', os.X_OK) File.executable?("/bin/ls")
external command
 
system("ls -l /tmp", $retval);
if ($retval) {
  throw new Exception("ls failed");
}
system("ls -l /tmp") == 0 or
  die "ls failed";
if os.system('ls -l /tmp'):
  raise Exception('ls failed')
unless system("ls -l /tmp")
  raise "ls failed"
end
escaped external command
 
$path = chop(fgets(STDIN));
$safe = escapeshellarg($path);
system("ls -l " . $safe, $retval);
if ($retval) {
  throw new Exception("ls failed");
}
$path = <>;
chomp($path);
system("ls""-l", $path) == 0 or
  die "ls failed";
import subprocess

cmd = ['ls''-l''/tmp']
if subprocess.call(cmd):
  raise Exception('ls failed')
path = gets
path.chomp!
unless system("ls""-l", path)
  raise "ls failed"
end
backticks
 
$files = `ls -l /tmp`; my $files = `ls -l /tmp`or
my $files = qx(ls);
import subprocess

cmd = ['ls''-l''/tmp']
files = subprocess.check_output(cmd)
files = `ls -l /tmp`
unless $?.success?
  raise "ls failed"
end

files = %x(ls)
unless $?.success?
  raise "ls failed"
end
  __________________________________________ __________________________________________ __________________________________________ __________________________________________

sheet two: libraries and modules | objects | reflection | web | tests | debugging and profiling | java interop

General Footnotes

versions used

The versions used for testing code in the reference sheet.

implicit prologue

Code which examples in the sheet assume to have already been executed.

perl:

We adopt the convention that if an example uses a variable without declaring it, it should be taken to have been previously declared with my.

python:

To keep the examples short we assume that osre, and sys are always imported.

show version

How to get the version.

php:

The function phpversion() will return the version number as a string.

perl:

Also available in the predefined variable $], or in a different format in $^V and $PERL_VERSION.

python:

The following function will return the version number as a string:

import platform
platform.python_version()

ruby:

Also available in the global constant VERSION (Ruby 1.8) or RUBY_VERSION (Ruby 1.9).

interpreter

The customary name of the interpreter and how to invoke it.

php:

php -f will only execute portions of the source file within a php code ?> tag as php code. Portions of the source file outside of such tags is not treated as executable code and is echoed to standard out.

If short tags are enabled, then php code can also be placed inside php code ?> and php code ?> tags.

php code ?> is identical to php code ?>.

repl

The customary name of the repl.

php:

The php REPL does not save or display the result of an expression.

php -a offers a different style of interactive mode. It collects input until EOF is encountered and then it executes it. Text inside  code ?> and  code ?> is executed as PHP code. Text outside of PHP markup tags is echoed.

perl:

The Perl REPL perl -de 0 does not save or display the result of an expression. perl -d is the Perl debugger and perl -e runs code provided on the command line.

perl -de 0 does not by default have readline, but it can be added:

$ cpan -i Term::Readline::Perl

  

$ perl -de 0

  DB<1> use Term::Readline::Perl;

  DB<2> print 1 + 1;
2

python:

The python repl saves the result of the last statement in _.

ruby:

irb saves the result of the last statement in _.

command line script

How to pass the code to be executed to the interpreter as a command line argument.

statement separator

How the parser determines the end of a statement.

php:

Inside braces statements must be terminated by a semicolon. The following causes a parse error:


The last statement inside  or  tags does not need to be semicolon terminated, however. The following code is legal:



perl:

In a script statements are separated by semicolons and never by newlines. However, when using 'perl -de 0', a newline terminates the statement.

python:

Newline does not terminate a statement when:

  • inside parens
  • inside list [] or dictionary {} literals

Python single quote '' and double quote "" strings cannot contain newlines except as the two character escaped form \n. Putting a newline in these strings results in a syntax error. There is however a multi-line string literal which starts and ends with three single quotes ''' or three double quotes: """.

A newline that would normally terminate a statement can be escaped with a backslash.

ruby:

Newline does not terminate a statement when:

  • inside single quotes '', double quotes "", backticks ``, or parens ()
  • after an operator such as + or , that expects another argument

Ruby permits newlines in array [] or hash literals, but only after a comma , or associator =>. Putting a newline before the comma or associator results in a syntax error.

A newline that would normally terminate a statement can be escaped with a backslash.

block delimiters

How blocks are delimited.

perl:

Curly brackets {} delimit blocks. They are also used for:

  • hash literal syntax which returns a reference to the hash: $rh = { 'true' => 1, 'false' => 0 }
  • hash value lookup: $h{'true'}, $rh->{'true'}
  • variable name delimiter: $s = "hello"; print "${s}goodbye";

python:

Python blocks begin with a line that ends in a colon. The block ends with the first line that is not indented further than the initial line. Python raises an IndentationError if the statements in the block that are not in a nested block are not all indented the same. Using tabs in Python source code is unrecommended and many editors replace them automatically with spaces. If the Python interpreter encounters a tab, it is treated as 8 spaces.

The python repl switches from a >>> prompt to a … prompt inside a block. A blank line terminates the block.

ruby:

Curly brackets {} delimit blocks. A matched curly bracket pair can be replaced by the do and end keywords. By convention curly brackets are used for one line blocks.

The end keyword also terminates blocks started by defclass, or module.

Curly brackets are also used for hash literals, and the #{ } notation is used to interpolate expressions into strings.

assignment

How to assign a value to a variable.

perl:

Assignment operators have right precedence and evaluate to the right argument, so assignments can be chained:

$a = $b = 3;

python:

If the variable on the left has not previously been defined in the current scope, then it is created. This may hide a variable in a containing scope.

Assignment does not return a value and cannot be used in an expression. Thus, assignment cannot be used in a conditional test, removing the possibility of using assignment (=) in place of an equality test (==). Assignments can nevertheless be chained to assign a value to multiple variables:

a = b = 3

ruby:

Assignment operators have right precedence and evaluate to the right argument, so they can be chained. If the variable on the left does not exist, then it is created.

parallel assignment

How to assign values to variables in parallel.

python:

The r-value can be a list or tuple:

nums = [1,2,3]
a,b,c = nums
more_nums = (6,7,8)
d,e,f = more_nums

Nested sequences of expression can be assigned to a nested sequences of l-values, provided the nesting matches. This assignment will set a to 1, b to 2, and c to 3:

(a,[b,c]) = [1,(2,3)]

This assignment will raise a TypeError:

(a,(b,c)) = ((1,2),3)

In Python 3 the splat operator * can be used to collect the remaining right side elements in a list:

x, y, *z = 1, 2        # assigns [] to z
x, y, *z = 1, 2, 3     # assigns [3] to z
x, y, *z = 1, 2, 3, 4  # assigns [3, 4] to z

ruby:

The r-value can be an array:

nums = [1,2,3]
a,b,c = nums

swap

How to swap the values held by two variables.

compound assignment

Compound assignment operators mutate a variable, setting it to the value of an operation which takes the value of the variable as an argument.

First row: arithmetic operator assignment: addition, subtraction, multiplication, (float) division, integer division, modulus, and exponentiation.
Second row: string concatenation assignment and string replication assignment
Third row: logical operator assignment: and, or, xor
Fourth row: bit operator assignment: left shift, right shift, and, or, xor.

python:

Python compound assignment operators do not return a value and hence cannot be used in expressions.

increment and decrement

The C-style increment and decrement operators can be used to increment or decrement values. They return values and thus can be used in expressions. The prefix versions return the value in the variable after mutation, and the postfix version return the value before mutation.

Incrementing a value two or more times in an expression makes the order of evaluation significant:

x = 1;
foo(++x, ++x); // foo(2, 3) or foo(3, 2)?

x = 1;
y = ++x/++x;  // y = 2/3 or y = 3/2?

Python avoids the problem by not having an in-expression increment or decrement.

Ruby mostly avoids the problem by providing a non-mutating increment and decrement. However, here is a Ruby expression which is dependent on order of evaluation:

x = 1
y = (x += 1)/(x += 1)

php:

The increment and decrement operators also work on strings. There are postfix versions of these operators which evaluate to the value before mutation:

$x = 1;
$x++;
$x--;

perl:

The increment and decrement operators also work on strings. There are postfix versions of these operators which evaluate to the value before mutation:

$x = 1;
$x++;
$x--;

ruby:

The Integer class defines succpred, and next, which is a synonym for succ.

The String class defines succsucc!next, and next!succ! and next! mutate the string.

local variable declarations

How to declare variables which are local to the scope defining region which immediately contain them.

php:

Variables do not need to be declared and there is no syntax for declaring a local variable. If a variable with no previous reference is accessed, its value is NULL.

perl:

Variables don't need to be declared unless use strict is in effect.

If not initialized, scalars are set to undef, arrays are set to an empty array, and hashes are set to an empty hash.

Perl can also declare variables with local. These replace the value of a global variable with the same name, if any, for the duration of the enclosing scope, after which the old value is restored. local declarations became obsolete with the introduction of the my declaration introduced in Perl 5.

python:

A variable is created by assignment if one does not already exist. If the variable is inside a function or method, then its scope is the body of the function or method. Otherwise it is a global.

ruby:

Variables are created by assignment. If the variable does not have a dollar sign ($) or ampersand (@) as its first character then its scope is scope defining region which most immediately contains it.

A lower case name can refer to a local variable or method. If both are defined, the local variable takes precedence. To invoke the method make the receiver explicit: e.g. self.name. However, outside of class and modules local variables hide functions because functions are private methods in the class Object. Assignment to name will create a local variable if one with that name does not exist, even if there is a method name.

regions which define local scope

A list of regions which define a scope for the local variables they contain.

Local variables defined inside the region are only in scope while code within the region is executing. If the language does not have closures, then code outside the region has no access to local variables defined inside the region. If the language does have closures, then code inside the region can make local variables accessible to code outside the region by returning a reference.

A region which is top level hides local variables in the scope which contains it from the code it contains. A region can also be top level if the syntax requirements of the language prohibit it from being placed inside another scope defining region.

A region is nestable if it can be placed inside another scope defining region, and if code in the inner region can access local variables in the outer region.

php:

Only function bodies and method bodies define scope. Function definitions can be nested, but when this is done lexical variables in the outer function are not visible to code in the body of the inner function.

Braces can be used to set off blocks of codes in a manner similar to the anonymous blocks of Perl. However, these braces do not define a scope. Local variables created inside the braces will be visible to subsequent code outside of the braces.

Local variables cannot be created in class bodies.

perl:

A local variable can be defined outside of any function definition or anonymous block, in which case the scope of the variable is the file containing the source code. In this way Perl resembles Ruby and contrasts with PHP and Python. In PHP and Python, any variable defined outside a function definition is global.

In Perl, when a region which defines a scope is nested inside another, then the inner region has read and write access to local variables defined in the outer region.

Note that the blocks associated with the keywords ifunlesswhileuntilfor, and foreach are anonymous blocks, and thus any my declarations in them create variables local to the block.

python:

Only functions and methods define scope. Function definitions can be nested. When this is done, inner scopes have read access to variables defined in outer scopes. Attempting to write (i.e. assign) to a variable defined in an outer scope will instead result in a variable getting created in the inner scope. Python trivia question: what would happen if the following code were executed?

def foo():
    v = 1
    def bar():
        print(v)
        v = 2
        print(v)
    bar()

foo()

ruby:

Note that though the keywords ifunlesscasewhile, and until each define a block which is terminated by an end keyword, none of these blocks have their own scope.

Anonymous functions can be created with the lambda keyword. Ruby anonymous blocks can be provided after a function invocation and are bounded by curly brackets { } or the do and end keywords. Both anonymous functions and anonymous blocks can have parameters which are specified at the start of the block within pipes. Here are some examples:

id = lambda { |x| x }

[3,1,2,4].sort { |a,b| a <=> b }

10.times do |i|
  print "#{i}..." 
end

In Ruby 1.8, the scope of the parameter of an anonymous block or function or block is local to the block or function body if the name is not already bound to a variable in the containing scope. However, if it is, then the variable in the containing scope will be used. This behavior was changed in Ruby 1.9 so that parameters are always local to function body or block. Here is an example of code which behaves differently under Ruby 1.8 and Ruby 1.9:

x = 3
id = lambda { |x| x }
id.call(7)
puts x # 1.8 prints 7; 1.9 prints 3

Ruby 1.9 also adds the ability mark variables as local, even when they are already defined in the containing scope. All such variables are listed inside the parameter pipes, separated from the parameters by a semicolon:

x = 3
noop = lambda { |; x| x = 15 } # bad syntax under 1.8
noop.call
# x is still 3

global variable

How to declare and access a variable with global scope.

php:

A variable is global if it is used at the top level (i.e. outside any function definition) or if it is declared inside a function with the global keyword. A function must use theglobal keyword to access the global variable.

perl:

Undeclared variables, which are permitted unless use strict is in effect, are global. If use strict is in effect, a global can be declared at the top level of a package (i.e. outside any blocks or functions) with the our keyword. A variable declared with my inside a function will hide a global with the same name, if there is one.

python:

A variable is global if it is defined at the top level of a file (i.e. outside any function definition). Although the variable is global, it must be imported individually or be prefixed with the module name prefix to be accessed from another file. To be accessed from inside a function or method it must be declared with the global keyword.

ruby:

A variable is global if it starts with a dollar sign: $.

constant declaration

How to declare a constant.

php:

A constant can be declared inside a class:

class Math {
  const pi = 3.14;
}

Refer to a class constant like this:

Math::pi

ruby:

Capitalized variables contain constants and class/module names. By convention, constants are all caps and class/module names are camel case. The ruby interpreter does not prevent modification of constants, it only gives a warning. Capitalized variables are globally visible, but a full or relative namespace name must be used to reach them: e.g. Math::PI.

to-end-of-line comment

How to create a comment that ends at the next newline.

comment out multiple lines

How to comment out multiple lines.

python:

The triple single quote ''' and triple double quote """ syntax is a syntax for string literals.

null

The null literal.

null test

How to test if a variable contains null.

php:

$v == NULL does not imply that $v is NULL, since any comparison between NULL and a falsehood will return true. In particular, the following comparisons are true:

$v = NULL;
if ($v == NULL) { echo "true"; }

$v = 0;
if ($v == NULL) { echo "sadly true"; }

$v = '';
if ($v == NULL) { echo "sadly true"; }

perl:

$v == undef does not imply that $v is undef. Any comparison between undef and a falsehood will return true. The following comparisons are true:

$v = undef;
if ($v == undef) { print "true"; }

$v = 0;
if ($v == undef) { print "sadly true"; }

$v = '';
if ($v == undef) { print "sadly true"; }

undefined variable access

The result of attempting to access an undefined variable.

undefined test

php:

A test showing that isset is the logical negation of is_null.

perl:

Perl does not distinguish between unset variables and variables that have been set to undef. In perl, calling defined($a) does not result in a error if $a is undefined, even with the strict pragma.

Arithmetic and Logic Footnotes

true and false

Literals for the booleans.

These are the return values of the comparison operators.

php:

Any identifier which matches TRUE case-insensitive can be used for the TRUE boolean. Similarly for FALSE.

In general, PHP variable names are case-sensitive, but function names are case-insensitive.

When converted to a string for display purposes, TRUE renders as "1" and FALSE as "". The equality tests TRUE == 1 and FALSE == "" evaluate as TRUE but the equality tests TRUE === 1 and FALSE === "" evaluate as FALSE.

falsehoods

Values which behave like the false boolean in a conditional context.

Examples of conditional contexts are the conditional clause of an if statement and the test of a while loop.

python:

Whether a object evaluates to True or False in a boolean context can be customized by implementing a __nonzero__ (Python 2) or __bool__ (Python 3) instance method for the class.

logical operators

Logical and, or, and not.

php, perl, ruby:

&& and || have higher precedence than assignment, compound assignment, and the ternary operator (?:), which have higher precedence than and and or.

conditional expression

How to write a conditional expression. A ternary operator is an operator which takes three arguments. Since

condition ? true value : false value

is the only ternary operator in C, it is unambiguous to refer to it as the ternary operator.

python:

The Python conditional expression comes from Algol.

ruby:

The Ruby if statement is also an expression:

x = if x > 0
  x
else
  -x
end

comparison operators

Equality, inequality, greater than, less than, greater than or equal, less than or equal.

Also known as the relational operators.

php:

Most of the comparison operators will convert a string to a number if the other operand is a number. Thus 0 == "0" is true. The operators === and !== do not perform this conversion, so 0 === "0" is false.

perl:

The operators: == != > < >= <= convert strings to numbers before performing a comparison. Many string evaluate as zero in a numeric context and are equal according to the == operator. To perform a lexicographic string comparison, use: eqnegtltgele.

python:

Comparison operators can be chained. The following expressions evaluate to true:

1 < 2 < 3
1 == 1 != 2

In general if Ai are expressions and opi are comparison operators, then

    A1 op1 A2 op2 A3 … An opn An+1

is true if and only if each of the following is true

    A1 op1 A2
    A2 op2 A3
    
    An opn An+1

three value comparison

Binary comparison operators which return -1, 0, or 1 depending upon whether the left argument is less than, equal to, or greater than the right argument.

The <=> symbol is called the spaceship operator.

convert from string, to string

How to convert string data to numeric data and vice versa.

php:

PHP converts a scalar to the desired type automatically and does not raise an error if the string contains non-numeric data. If the start of the string is not numeric, the string evaluates to zero in a numeric context.

perl:

Perl converts a scalar to the desired type automatically and does not raise an error if the string contains non-numeric data. If the start of the string is not numeric, the string evaluates to zero in a numeric context.

python:

float and int raise an error if called on a string and any part of the string is not numeric.

ruby:

to_i and to_f always succeed on a string, returning the numeric value of the digits at the start of the string, or zero if there are no initial digits.

arithmetic operators

The operators for addition, subtraction, multiplication, float division, integer division, modulus, and exponentiation.

integer division

How to get the integer quotient of two integers. How to get the integer quotient and remainder.

perl:

The integer pragma makes all arithmetic operations integer operations. Floating point numbers are truncated before they are used. Hence integer division could be performed with:

use integer;
my $a = 7 / 3;
no integer;

float division

How to perform floating point division, even if the operands might be integers.

arithmetic functions

Some arithmetic functions. Trigonometric functions are in radians unless otherwise noted. Logarithms are natural unless otherwise noted.

python:

Python also has math.log10. To compute the log of x for base b, use:

math.log(x)/math.log(b)

ruby:

Ruby also has Math.log2Math.log10. To compute the log of x for base b, use

Math.log(x)/Math.log(b)

arithmetic truncation

How to truncate a float to the nearest integer towards zero; how to round a float to the nearest integer; how to find the nearest integer above a float; how to find the nearest integer below a float; how to take the absolute value.

perl:

The CPAN module Number::Format provides a round function. The 2nd argument specifies the number of digits to keep to the right of the radix. The default is 2.

use Number::Format 'round';

round(3.14, 0);

min and max

How to get the min and max.

division by zero

What happens when division by zero is performed.

integer overflow

What happens when the largest representable integer is exceeded.

float overflow

What happens when the largest representable float is exceeded.

sqrt -2

The result of taking the square root of negative two.

rational numbers

How to create rational numbers and get the numerator and denominator.

ruby:

Require the library mathn and integer division will yield rationals instead of truncated integers.

complex numbers

python:

Most of the functions in math have analogues in cmath which will work correctly on complex numbers.

random integer, uniform float, normal float

How to generate a random integer between 0 and 99, include, float between zero and one in a uniform distribution, or a float in a normal distribution with mean zero and standard deviation one.

set random seed, get and restore seed

How to set the random seed; how to get the current random seed and later restore it.

All the languages in the sheet set the seed automatically to a value that is difficult to predict. The Ruby 1.9 MRI interpreter uses the current time and process ID, for example. As a result there is usually no need to set the seed.

Setting the seed to a hardcoded value yields a random but repeatable sequence of numbers. This can be used to ensure that unit tests which cover code using random numbers doesn't intermittently fail.

The seed is global state. If multiple functions are generating random numbers then saving and restoring the seed may be necessary to produce a repeatable sequence.

bit operators

The bit operators for left shift, right shift, and, inclusive or, exclusive or, and negation.

binary, octal, and hex literals

Binary, octal, and hex integer literals

base conversion

How to convert integers to strings of digits of a given base. How to convert such strings into integers.

perl

Perl has the functions oct and hex which convert strings encoded in octal and hex and return the corresponding integer. The oct function will handle binary or hex encoded strings if they have "0b" or "0x" prefixes.

oct("60")
oct("060")
oct("0b101010")
oct("0x2a")

hex("2a")
hex("0x2a")

python

Python has the functions binoct, and hex which take an integer and return a string encoding the integer in base 2, 8, and 16.

bin(42)
oct(42)
hex(42)

String Footnotes

string literal

The syntax for string literals.

perl:

When use strict is not in effect bareword strings are permitted.

Barewords are strings without quote delimiters. They are a feature of shells. Barewords cannot contain whitespace or any other character used by the tokenizer to distinguish words.

Before Perl 5 subroutines were invoked with an ampersand prefix & or the older do keyword. With Perl 5 neither is required, but this made it impossible to distinguish a bareword string from a subroutine without knowing all the subroutines which are in scope.

The following code illustrates the bareword ambiguity:

no strict;

print rich . "\n";  # prints "rich"; rich is a bareword string

sub rich { return "poor" }

print rich . "\n";  # prints "poor"; rich is now a subroutine

newline in literal

Whether newlines are permitted in string literals.

python:

Newlines are not permitted in single quote and double quote string literals. A string can continue onto the following line if the last character on the line is a backslash. In this case, neither the backslash nor the newline are taken to be part of the string.

Triple quote literals, which are string literals terminated by three single quotes or three double quotes, can contain newlines:

'''This is
two lines'''

"""This is also
two lines"""

backslash escapes

Backslash escape sequences for inserting special characters into string literals.

python:

When string literals have an r or R prefix there are no backslash escape sequences and any backslashes thus appear in the created string. The delimiter can be inserted into a string if it is preceded by a backslash, but the backslash is also inserted. It is thus not possible to create a string with an r or R prefix that ends in a backslash. The r and R prefixes can be used with single or double quotes:

r'C:\Documents and Settings\Admin'
r"C:\Windows\System32"

The \uhhhh escapes are also available inside Python 2 Unicode literals. Unicode literals have a u prefiix:

u'lambda: \u03bb'

variable interpolation

How to interpolate variables into strings.

python:

str.format will take named or positional parameters. When used with named parameters str.format can mimic the variable interpolation feature of the other languages.

A selection of variables in scope can be passed explicitly:

count = 3
item = 'ball'
print('{count} {item}s'.format(
  count=count,
  item=item))

Python 3 has format_map which accepts a dict as an argument:

count = 3
item = 'ball'
print('{count} {item}s'.format_map(locals()))

custom delimiters

How to specify custom delimiters for single and double quoted strings. These can be used to avoid backslash escaping. If the left delimiter is (, [, or { the right delimiter must be ), ], or }, respectively.

sprintf

How to create a string using a printf style format.

python:

The % operator will interpolate arguments into printf-style format strings.

The str.format with positional parameters provides an alternative format using curly braces {0}, {1}, … for replacement fields.

The curly braces are escaped by doubling:

'to insert parameter {0} into a format, use {{{0}}}'.format(3)

If the replacement fields appear in sequential order and aren't repeated, the numbers can be omitted:

'lorem {} {} {}'.format('ipsum', 13, 3.7)

here document

Here documents are strings terminated by a custom identifier. They perform variable substitution and honor the same backslash escapes as double quoted strings.

perl:

Put the custom identifer in single quotes to prevent variable interpolation and backslash escape interpretation:

s = <<'EOF';
Perl code uses variables with dollar
signs, e.g. $var
EOF

python:

Python lacks variable interpolation in strings. Triple quotes honor the same backslash escape sequences as regular quotes, so triple quotes can otherwise be used like here documents:

s = '''here document
there computer
'''

ruby:

Put the customer identifier in single quotes to prevent variable interpolation and backslash escape interpretation:

s = <<'EOF'
Ruby code uses #{var} type syntax
to interpolate variables into strings.
EOF

concatenate

The string concatenation operator.

replicate

The string replication operator.

split, in two, with delimiters, into characters

How to split a string containing a separator into an array of substrings; how to split a string in two; how to split a string with the delimiters preserved as separate elements; how to split a string into an array of single character strings.

python:

str.split() takes simple strings as delimiters; use re.split() to split on a regular expression:

re.split('\s+', 'do re mi fa')
re.split('\s+', 'do re mi fa', 1)

join

How to concatenate the elements of an array into a string with a separator.

case manipulation

How to put a string into all caps or all lower case letters. How to capitalize the first letter of a string.

strip

How to remove whitespace from the ends of a string.

pad on right, on left

How to pad the edge of a string with spaces so that it is a prescribed length.

length

How to get the length in characters of a string.

index of substring

How to find the index of the leftmost occurrence of a substring in a string; how to find the index of the rightmost occurrence.

python:

Methods for splitting a string into three parts using the first or last occurrence of a substring:

'do re re mi'.partition('re')     # returns ('do ', 're', ' re mi')
'do re re mi'.rpartition('re')    # returns ('do re ', 're', ' mi')

extract substring

How to extract a substring from a string by index.

extract character

How to extract a character from a string by its index.

chr and ord

Converting characters to ASCII codes and back.

The languages in this reference sheet do not have character literals, so characters are represented by strings of length one.

character translation

How to apply a character mapping to a string.

Regular Expressions

  • PHP PCRE Regexes
  • perlre and perlreref
  • Python re library: 2.7, 3.1
  • Ruby Regexp

Regular expressions or regexes are a way of specifying sets of strings. If a string belongs to the set, the string and regex "match". Regexes can also be used to parse strings.

The modern notation for regexes was introduced by Unix command line tools in the 1970s. POSIX standardized the notation into two types: extended regexes and the more archaic basic regexes. Perl regexes are extended regexes augmented by new character class abbreviations and a few other features introduced by the Perl interpreter in the 1990s. All the languages in this sheet use Perl regexes.

Any string that doesn't contain regex metacharacters is a regex which matches itself. The regex metacharacters are: [ ] . | ( ) * + ? { } ^ $ \

character classes: [ ] .

A character class is a set of characters in brackets: [ ]. When used in a regex it matches any character it contains.

Character classes have their own set of metacharacters: ^ - \ ]

The ^ is only special when it the first character in the character class. Such a character class matches its complement; that is, any character not inside the brackets. When not the first character the ^ refers to itself.

The hypen is used to specify character ranges: e.g. 0-9 or A-Z. When the hyphen is first or last inside the brackets it matches itself.

The backslash can be used to escape the above characters or the terminal character class delimiter: ]. It can be used in character class abbreviations or string backslash escapes.

The period . is a character class abbreviation which matches any character except for newline. In all languages the period can be made to match all characters. In PHP and Perl use the m modifer. In Python use the re.M flag. In Ruby use the s modifer.


character class abbreviations:

abbrev name character class
\d digit [0-9]
\D nondigit [^0-9]
\h PHP, Perl: horizontal whitespace character
Ruby: hex digit
PHP, Perl: [ \t]
Ruby: [0-9a-fA-F]
\H PHP, Perl: not a horizontal whitespace character
Ruby: not a hex digit
PHP, Perl: [^ \t]
Ruby: [^0-9a-fA-F]
\s whitespace character [ \t\r\n\f]
\S non whitespace character [^ \t\r\n\f]
\v vertical whitespace character [\r\n\f]
\V not a vertical whitespace character [^\r\n\f]
\w word character [A-Za-z0-9_]
\W non word character [^A-Za-z0-9_]

alternation and grouping: | ( )

The vertical pipe | is used for alternation and parens () for grouping.

A vertical pipe takes as its arguments everything up to the next vertical pipe, enclosing paren, or end of string.

Parentheses control the scope of alternation and the quantifiers described below. The are also used for capturing groups, which are the substrings which matched parenthesized parts of the regular expression. Each language numbers the groups and provides a mechanism for extracting when a match is made. A parenthesized subexpression can be removed from the groups with this syntax: (?:expr)

quantifiers: * + ? { }

As an argument quantifiers take the preceding regular character, character class, or group. The argument can itself be quantified, so that ^a{4}*$ matches strings with the letter a in multiples of 4.

quantifier # of occurrences of argument matched
* zero or more, greedy
+ one or more, greedy
? zero or one, greedy
{m,n} m to n, greedy
{n} exactly n
{m,} m or more, greedy
{,n} zero to n, greedy
*? zero or more, lazy
+? one or more, lazy
{m,n}? m to n, lazy
{m,}? m or more, lazy
{,n}? zero to n, lazy

When there is a choice, greedy quantifiers will match the maximum possible number of occurrences of the argument. Lazy quantifiers match the minimum possible number.


anchors: ^ $

anchor matches
^ beginning of a string. In Ruby or when m modifier is used also matches right side of a newline
$ end of a string. In Ruby or when m modifier is used also matches left side of a newline
\A beginning of the string
\b word boundary. In between a \w and a \W character or in between a \w character and the edge of the string
\B not a word boundary. In between two \w characters or two \W characters
\z end of the string
\Z end of the string unless it is a newline, in which case it matches the left side of the terminal newline

escaping: \

To match a metacharacter, put a backslash in front of it. To match a backslash use two backslashes.

php:

PHP 5.3 still supports the EREG engine, though the functions which use it are deprecated. These include the split function and functions which start with ereg. The preferred functions are preg_split and the other functions with a preg prefix.

literal, custom delimited literal

The literal for a regular expression; the literal for a regular expression with a custom delimiter.

php:

PHP regex literals are strings. The first character is the delimiter and it must also be the last character. If the start delimiter is (, {, or [ the end delimiter must be ), }, or ], respectively.

Here are the signatures from the PHP manual for the preg functions used in this sheet:

array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )

int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )

python:

Python does not have a regex literal, but the re.compile function can be used to create regex objects.

Compiling regexes can always be avoided:

re.compile('\d{4}').search('1999')
re.search('\d{4}', '1999')

re.compile('foo').sub('bar', 'foo bar')
re.sub('foo', 'bar', 'foo bar')

re.compile('\w+').findall('do re me')
re.findall('\w+', 'do re me')

character class abbreviations and anchors

The supported character class abbreviations and anchors.

Note that \h refers to horizontal whitespace (i.e. a space or tab) in PHP and Perl and a hex digit in Ruby. Similarly \H refers to something that isn't horizontal whitespace in PHP and Perl and isn't a hex digit in Ruby.

match test

How to test whether a string matches a regular expression.

python:

The re.match function is like the re.search function, except that it is only true if the regular expression matches the entire string.

ruby:

match is a method of both Regexp and String so can match with both

/1999/.match("1999")

and

"1999".match(/1999/)

When variables are involved it is safer to invoke the Regexp method because string variables are more likely to contain nil.

case insensitive match test

How to perform a case insensitive match test.

modifiers

Modifiers that can be used to adjust the behavior of a regular expression.

The lists are not comprehensive. For all languages except Ruby there are additional modifiers.

modifier behavior
e PHP: when used with preg_replace, the replacement string, after backreferences are substituted, is eval'ed as PHP code and the result is used as the replacement.
i, re.I all: ignores case. Upper case letters match lower case letters and vice versa.
m, re.M PHP, Perl, Python: makes the ^ and $ match the right and left edge of newlines in addition to the beginning and end of the string.
Ruby: makes the period . match newline characters.
o Ruby: performs variable interpolation #{ } only once per execution of the program.
p Perl: sets ${^MATCH} ${^PREMATCH} and ${^POSTMATCH}
s, re.S PHP, Perl, Python: makes the period . match newline characters.
x, re.X all: ignores whitespace in the regex which permits it to be used for formatting.

Python modifiers are bit flags. To use more than one flag at the same time, join them with bit or: |

substitution

How to replace all occurrences of a matching pattern in a string with the provided substitution string.

php:

The number of occurrences replaced can be controlled with a 4th argument to preg_replace:

$s = "foo bar bar";
preg_replace('/bar/', "baz", $s, 1);

If no 4th argument is provided, all occurrences are replaced.

perl:

The =~ operator performs the substitution in place on the string and returns the number of substitutions performed.

The g modifiers specifies that all occurrences should be replaced. If omitted, only the first occurrence is replaced.

python:

The 3rd argument to sub controls the number of occurrences which are replaced.

s = 'foo bar bar'
re.compile('bar').sub('baz', s, 1)

If there is no 3rd argument, all occurrences are replaced.

ruby:

The gsub operator returns a copy of the string with the substitution made, if any. The gsub! performs the substitution on the original string and returns the modified string.

The sub and sub! operators only replace the first occurrence of the match pattern.

match, prematch, postmatch

How to get the substring that matched the regular expression, as well as the part of the string before and after the matching substring.

perl:

The special variables $&$`, and $' also contain the match, prematch, and postmatch.

ruby:

The special variables $&$`, and $' also contain the match, prematch, and postmatch.

group capture

How to get the substrings which matched the parenthesized parts of a regular expression.

ruby:

Ruby has syntax for extracting a group from a match in a single expression. The following evaluates to "1999":

"1999-07-08"[/(\d{4})-(\d{2})-(\d{2})/, 1]

scan

How to return all non-overlapping substrings which match a regular expression as an array.

backreference in match and substitution

How to use backreferences in a regex; how to use backreferences in the replacement string of substitution.

recursive regex

Examples of recursive regexes.

The examples match substrings containing balanced parens.

Date and Time Footnotes

In ISO 8601 terminology, a date specifies a day in the Gregorian calendar and a time does not contain date information; it merely specifies a time of day. A data type which combines both date and time information is probably more useful than one which contains just date information or just time information; it is unfortunate that ISO 8601 doesn't provide a name for this entity. The word timestamp often gets used to denote a combined date and time. PHP and Python use the compound noundatetime for combined date and time values.

An useful property of ISO 8601 dates, times, and date/time combinations is that they are correctly ordered by a lexical sort on their string representations. This is because they are big-endian (the year is the leftmost element) and they used fixed-length fields for each term in the string representation.

The C standard library provides two methods for representing dates. The first is the UNIX epoch, which is the seconds since January 1, 1970 in UTC. If such a time were stored in a 32-bit signed integer, the rollover would happen on January 18, 2038.

The other method of representing dates is the tm struct, a definition of which can be found on Unix systems in /usr/include/time.h:

struct tm {
        int     tm_sec;         /* seconds after the minute [0-60] */
        int     tm_min;         /* minutes after the hour [0-59] */
        int     tm_hour;        /* hours since midnight [0-23] */
        int     tm_mday;        /* day of the month [1-31] */
        int     tm_mon;         /* months since January [0-11] */
        int     tm_year;        /* years since 1900 */
        int     tm_wday;        /* days since Sunday [0-6] */
        int     tm_yday;        /* days since January 1 [0-365] */
        int     tm_isdst;       /* Daylight Savings Time flag */
        long    tm_gmtoff;      /* offset from CUT in seconds */
        char    *tm_zone;       /* timezone abbreviation */
};

Perl and Python both use and expose the tm struct of the standard library. In the case of Perl, the first nine values of the struct (up to the member tm_isdst) are put into an array. Python, meanwhile, has a module called time which is a thin wrapper to the standard library functions which operate on this struct. Here is how get a tmstruct in Python:

import time

utc = time.gmtime(time.time())
t = time.localtime(time.time())

The tm struct is a low level entity, and interacting with it directly should be avoided. In the case of Python it is usually sufficient to use the datetime module instead. For Perl, one can use the Time::Piece module to wrap the tm struct in an object.

date/time type

The data type used to hold a combined date and time.

perl

Built in Perl functions work with either (1) scalars containing the Unix epoch as an integer or (2) arrays containing the first nine values of the standard C library tm struct. When use Time::Piece is in effect functions which work with tm arrays are replaced with variant that work with the Time::Piece wrapper.

The modules Time::Local and Date::Parse can create scalars containing the Unix epoch.

CPAN provides the DateTime module which provides objects with functionality comparable to the DateTime objects of PHP and Python.

current date/time

How to get the combined date and time for the present moment in both local time and UTC.

to unix epoch, from unix epoch

How to convert the native date/time type to the Unix epoch which is the number of seconds since the start of January 1, 1970 UTC.

current unix epoch

How to get the current time as a Unix epoch timestamp.

strftime

How to format a date/time as a string using the format notation of the strftime function from the standard C library. This same format notation is used by the Unix datecommand.

php:

PHP supports strftime but it also has its own time formatting system used by dateDateTime::format, and DateTime::createFromFormat. The letters used in the PHP time formatting system are described here.

default format example

Examples of how a date/time object appears when treated as a string such as when it is printed to standard out.

The formats are in all likelihood locale dependent. The provided examples come from a machine running Mac OS X in the Pacific time zone of the USA.

php:

It is a fatal error to treat a DateTime object as a string.

strptime

How to parse a date/time using the format notation of the strptime function from the standard C library.

parse date w/o format

How to parse a date without providing a format string.

result date subtraction

The data type that results when subtraction is performed on two combined date and time values.

add time duration

How to add a time duration to a date/time.

A time duration can easily be added to a date/time value when the value is a Unix epoch value.

ISO 8601 distinguishes between a time interval, which is defined by two date/time endpoints, and a duration, which is the length of a time interval and can be defined by a unit of time such as '10 minutes'. A time interval can also be defined by date and time representing the start of the interval and a duration.

ISO 8601 defines notation for durations. This notation starts with a 'P' and uses a 'T' to separate the day and larger units from the hour and smaller units. Observing the location relative to the 'T' is important for interpreting the letter 'M', which is used for both months and minutes.

local timezone

Do date/time values include timezone information. When a date/time value for the local time is created, how the local timezone is determined.

A date/time value can represent a local time but not have any timezone information associated with it.

On Unix systems processes determine the local timezone by inspecting the file /etc/localtime.

php:

The default timezone can also be set in the php.ini file.

date.timezone = "America/Los_Angeles"

Here is the list of timezones supported by PHP.

timezone name, offset from UTC, is daylight savings?

How to get time zone information: the name of the timezone, the offset in hours from UTC, and whether the timezone is currently in daylight savings.

Timezones are often identified by three or four letter abbreviations. As can be seen from the list, many of the abbreviations do not uniquely identify a timezone. Furthermore many of the timezones have been altered in the past. The Olson database (aka Tz database) decomposes the world into zones in which the local clocks have all been set to the same time since 1970 and it gives these zones unique names.

perl:

It is not necessary to create a DateTime object to get the local timezone offset:

use Time::Piece;

$t = localtime(time);
$offset_hrs = $t->tzoffset / 3600;

ruby:

The Time class has a zone method which returns the time zone abbreviation for the object. There is a tzinfo gem which can be used to create timezone objects using the Olson database name. This can in turn be used to convert between UTC times and local times which are daylight saving aware.

microseconds

How to get the microseconds component of a combined date and time value. The SI abbreviations for milliseconds and microseconds are ms and μs, respectively. The C standard library uses the letter u as an abbreviation for micro. Here is a struct defined in /usr/include/sys/time.h:

struct timeval {
  time_t       tv_sec;   /* seconds since Jan. 1, 1970 */
  suseconds_t  tv_usec;  /* and microseconds */
};

sleep

How to put the process to sleep for a specified number of seconds. In Python and Ruby the default version of sleep supports a fractional number of seconds.

php:

PHP provides usleep which takes an argument in microseconds:

usleep(500000);

perl:

The Perl standard library includes a version of sleep which supports fractional seconds:

use Time::HiRes qw(sleep);

sleep 0.5;

timeout

How to cause a process to timeout if it takes too long.

Techniques relying on SIGALRM only work on Unix systems.

Array Footnotes

What the languages call their basic container types:

  php perl python ruby
array array

你可能感兴趣的:(PHP,python)