スクリプト言語の比較

スクリプト言語の比較

http://hyperpolyglot.org/scripting より

show version
PHP
$ php --version
Perl
$ perl --version
Python
$ python -V
Ruby
$ ruby --version


interpreter
PHP
$ php -f foo.php
Perl
$ perl foo.pl
Python
$ python foo.py
Ruby
$ ruby foo.rb


repl
PHP
$ php -a
Perl
$ perl -de 0
Python
$ python
Ruby
$ irb


check syntax
PHP
$ php -l foo.php
Perl
$ perl -c foo.pl
Python
# precompile to bytecode:
import py_compile
py_compile.compile("foo.py")
Ruby
$ ruby -c foo.rb


flags for stronger and strongest warnings
PHP
none
Perl
$ perl -w foo.pl
$ perl -W foo.pl
Python
$ python -t foo.py
$ python -3t foo.py
Ruby
$ ruby -w foo.pl
$ ruby -W2 foo.pl


statement separator
PHP
;
Perl
;
Python
; # or sometimes newline
Ruby
; # or sometimes newline


block delimiters
PHP
{}
Perl
{}
Python
offside rule
Ruby
{}
do end


assignment
PHP
$a = 1;
Perl
$a = 1;
Python
# does not return a value:
a = 1
Ruby
a = 1


parallel assignment
PHP
list($a, $b, $c) = array(1 ,2, 3);
# 3 is ignored:
list($a, $b) = array(1, 2, 3);
# $c set to NULL:
list($a, $b, $c) = array(1, 2);
Perl
($a, $b, $c) = (1, 2, 3);
# 3 is ignored:
($a, $b) = (1, 2, 3);
# $c set to undef:
($a, $b, $c) = (1, 2);
Python
a, b, c = 1, 2, 3
# raises ValueError:
a, b = 1, 2, 3
# raises ValueError:
a, b, c = 1, 2
Ruby
a, b, c = 1, 2, 3
# 3 is ignored:
a, b = 1, 2, 3
# c set to nil:
a, b, c = 1, 2


swap
PHP
list($a, $b) = array($b, $a);
Perl
($a, $b) = ($b, $a);
Python
a, b = b, a
Ruby
a, b = b, a


compound assignment operators: arithmetic, string, logical, bit
PHP
+= -= *= none /= %= **=
.= none
&= |= none
<<= >>= &= |= ^=
Perl
+= -= *= none /= %= **=
.= x=
&&= ||= ^=
<<= >>= &= |= ^=
Python
# do not return values:
+= -= *= /= //= %= **=
+= *=
&= |= ^=
<<= >>= &= |= ^=
Ruby
+= -= *= /= none %= **=
+= *=
&&= ||= ^=
<<= >>= &= |= ^=


increment and decrement
PHP
$x = 1;
++$x;
--$x;
Perl
$x = 1;
++$x;
--$x;
Python
none
Ruby
# x not mutated:
x = 1
x.succ
x.pred


local variable declarations
PHP
# in function body:
$a = NULL;
$b = array();
$c = array();
$d = 1;
list($e, $f) = array(2, 3);
Perl
my $a;
my (@b, %c);
my $d = 1;
my ($e, $f) = (2, 3);
Python
# in function body:
a = None
b, c = [], {}
d = 1
e, f = 2, 3
Ruby
a = nil
b, c = [], {}
d = 1
e, f = 2, 3


regions which define local scope
PHP
top level:
  function or method body

nestable (with use clause):
  anonymous function body

Perl
top level:
  file

nestable:
  function body
  anonymous function body
  anonymous block

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

nestable:
  anonymous function block
  anonymous block


global variable
PHP
list($g, $h) = array(7, 8);
function swap_globals() {
  global $g, $h;
  list($g, $h) = array($h, $g);
}
Perl
our ($g, $h) = (7, 8);
sub swap_globals() {
  ($g, $h) = ($h, $g);
}
Python
g, h = 7, 8
def swap_globals():
  global g, h
  g, h = h, g
Ruby
$g, $h = 7, 8
def swap_globals()
  $g, $h = $h, $g
end


constant declaration
PHP
class Math {
  const pi = 3.14;
}
# how to reference constant:
Math::pi
Perl
use constant PI => 3.14;
Python
# uppercase identifiers
# constant by convention

PI = 3.14
Ruby
# warning if capitalized
# identifier is reassigned

PI = 3.14


to-end-of-line comment
PHP
// comment
# comment
Perl
# comment
Python
# comment
Ruby
# comment


multiline comment
PHP
/* comment line
another line */
Perl
=for
comment line
another line
=cut
Python
'''comment line
another line'''
Ruby
=begin
comment line
another line
=end


null
PHP
NULL # case insensitive
Perl
undef
Python
None
Ruby
nil


null test
PHP
is_null($v)
! isset($v)
Perl
! defined $v
Python
v == None
v is None
Ruby
v == nil
v.nil?


undefined variable access
PHP
NULL
Perl
error under use strict; otherwise undef
Python
raises NameError
Ruby
raises NameError


undefined test
PHP
same as null test; no distinction between undefined variables and variables set to NULL
Perl
same as null test; no distinction between undefined variables and variables set to undef
Python
not_defined = False
try: v
except NameError: not_defined = True
Ruby
! defined?(v)


arithmetic and logic

true and false
PHP
TRUE FALSE # case insensitve
Perl
1 0
Python
True False
Ruby
true false


falsehoods
PHP
FALSE NULL 0 0.0 '' '0' array()
Perl
undef 0 0.0 '' '0' ()
Python
False None 0 0.0 '' [] {}
Ruby
false nil


logical operators
PHP
&& || ! lower precedence: and or xor
Perl
and or not also: && || !
Python
and or not
Ruby
and or not also: && || !


conditional expression
PHP
$x > 0 ? $x : -$x
Perl
$x > 0 ? $x : -$x
Python
x if x > 0 else -x
Ruby
x > 0 ? x : -x


comparison operators
PHP
== != or <> > < >= <=
no conversion: === !==
Perl
numbers only: == != > < >= <=
strings: eq ne gt lt ge le
Python
== != > < >= <=
Ruby
== != > < >= <=


convert from string, to string
PHP
7 + '12'
73.9 + '.037'
'value: ' . 8
Perl
7 + '12'
73.9 + '.037'
'value: ' . 8
Python
7 + int('12')
73.9 + float('.037')
'value: ' + str(8)
Ruby
7 + "12".to_i
73.9 + ".037".to_f
"value: " + "8".to_s


arithmetic operators
PHP
+ - * / none % pow(b,e)
Perl
+ - * / none % **
Python
+ - * / // % **
Ruby
+ - * x.fdiv(y) / % **


integer division
PHP
(int) ($a / $b)
Perl
int ( $a / $b )
Python
a // b
Ruby
a / b


float division
PHP
$a / $b
Perl
$a / $b
Python
float(a) / b
# python 3:
a / b
Ruby
a.to_f / b or
a.fdiv(b)


arithmetic functions
PHP
sqrt exp log sin cos tan asin acos atan atan2
Perl
sqrt exp log sin cos none none none none atan2
Python
from math import sqrt, exp, log, \
sin, cos, tan, asin, acos, atan, atan2
Ruby
include Math
sqrt exp log sin cos tan asin acos atan atan2


arithmetic truncation
PHP
abs($x)
round($x)
ceil($x)
floor($x)
Perl
abs($x)
none
POSIX:
ceil($x)
floor($x)
Python
import math
abs(x)
int(round(x))
math.ceil(x)
math.floor(x)
Ruby
x.abs
x.round
x.ceil
x.floor


min and max
PHP
min(1,2,3)
max(1,2,3)
# of an array:
$a = array(1,2,3)
call_user_func_array(min, $a)
call_user_func_array(max, $a)
Perl
use List::Util qw( min max);
min(1,2,3);
max(1,2,3);
@a = (1,2,3);
min(@a);
max(@a);
Python
min(1,2,3)
max(1,2,3)
min([1,2,3])
max([1,2,3])
Ruby
[1,2,3].min
[1,2,3].max


division by zero
PHP
returns zero with warning
Perl
error
Python
raises ZeroDivisionError
Ruby
integer division raises ZeroDivisionError
float division returns Infinity


integer overflow
PHP
converted to float
Perl
converted to float
Python
becomes arbitrary length integer of type long
Ruby
becomes arbitrary length integer of type Bignum


float overflow
PHP
INF
Perl
inf
Python
raises OverflowError
Ruby
Infinity


sqrt -2
PHP
NaN
Perl
error
Python
# raises ValueError:
import math
math.sqrt(-2)
# returns complex float:
import cmath
cmath.sqrt(-2)
Ruby
raises Errno::EDOM


rational numbers
PHP
none
Perl
none
Python
from fractions import Fraction
x = Fraction(22,7)
x.numerator
x.denominator
Ruby
require 'rational'
x = Rational(22,7)
x.numerator
x.denominator


complex numbers
PHP
none
Perl
none
Python
z = 1 + 1.414j
z.real
z.imag
Ruby
require 'complex'
z = 1 + 1.414.im
z.real
z.imag


random integer, uniform float, normal float
PHP
rand(0,99)
lcg_value()
none
Perl
int(rand() * 100)
rand()
none
Python
import random
random.randint(0,99)
random.random()
random.gauss(0,1)
Ruby
rand(100)
rand
none


bit operators
PHP
<< >> & | ^ ~
Perl
<< >> & | ^ ~
Python
<< >> & | ^ ~
Ruby
<< >> & | ^ ~


strings

character literal
PHP
none
Perl
none
Python
none
Ruby
none


chr and ord
PHP
chr(65)
ord("A")
Perl
chr(65)
ord("A")
Python
chr(65)
ord('A')
Ruby
65.chr
"A".ord


string literal
PHP
'don\'t say "no"'
"don't say \"no\""
Perl
'don\'t say "no"'
"don't say \"no\""
Python
'don\'t say "no"'
"don't say \"no\""
Ruby
'don\'t say "no"'
"don't say \"no\""


newline in literal
PHP
yes
Perl
yes
Python
no, use escape or triple quote literal
Ruby
yes


here document
PHP
$computer = 'PC';
$s = <<<EOF
here document
there $computer
EOF
;
Perl
$computer = 'PC';
$s = <<EOF;
here document
there $computer

EOF
Python
none
Ruby
computer = 'PC'
s = <<EOF
here document
there
#{computer}
EOF


escapes
PHP
single quoted:
\' \\
double quoted:
\f \n \r \t \v \xhh \$ \" \ooo
Perl
single quoted:
\' \\
double quoted:
\a \b \cx \e \f \n \r \t \xhh \x{hhhh} \ooo
Python
\newline \\ \' \" \a \b \f \n \r \t \v \ooo \xhh
# python 3:
\uhhhh
Ruby
# single quoted:
\' \\
# double quoted:
\a \b \cx \e \f \n \r \s \t \uhhhh \u{hhhhh} \v \xhh \ooo


encoding
PHP
Perl
Python
Ruby


variable interpolation
PHP
$count = 3;
$item = "ball";
echo "$count ${item}s\n";
Perl
my $count = 3;
my $item = "ball";
print "$count ${item}s\n";
Python
none
Ruby
count = 3
item = "ball"
puts "#{count} #{item}s"


length
PHP
strlen("hello")
Perl
length("hello")
Python
len('hello')
Ruby
"hello".length
"hello".size


character count
PHP
$a = count_chars("(3*(7+12))");
$a[ord('(')]
Perl
"(3*(7+12))" =~ tr/(//
Python
'(3*(7+12))'.count('(')
Ruby
'(3*(7+12))'.count('(')


index of substring
PHP
strpos("foo bar", "bar")
Perl
index("foo bar","bar")
Python
'foo bar'.index('bar')
Ruby
"foo bar".index("bar")


extract substring
PHP
substr("foo bar", 4, 3)
Perl
substr("foo bar",4,3)
Python
"foo bar"[4:7]
Ruby
"foo bar"[4,3]


concatenate
PHP
"hello, " . "world"
Perl
"hello, " . "world"
Python
'hello, ' + 'world'
Ruby
"hello, " + "world"


replicate
PHP
$hbar = str_repeat('-', 80);
Perl
my $hbar = '-' x 80;
Python
hbar = '-' * 80
Ruby
hbar = '-' * 80


split
PHP
explode(" ","foo bar baz")
preg_split('/\s+/',"foo bar baz")
Perl
split(/\s+/,"foo bar baz")
Python
'foo bar baz'.split()
Ruby
"foo bar baz".split


join
PHP
$a = array("foo","bar","baz");
implode(" ", $a)
Perl
join(' ',("foo","bar","baz"))
Python
' '.join(['foo','bar','baz'])
Ruby
['foo','bar','baz'].join(' ')


scan
PHP
$s = "foo bar baz";
preg_match_all('/\w+/', $s, $a);
$a[0]
Perl
none
Python
import re
s = 'foo bar baz'
re.compile('\w+').findall(s)
Ruby
"foo bar baz".scan(/\w+/)


pack and unpack
PHP
$f="a3ilfd";
$s=pack($f,"hello",7,7,3.14,3.14);
unpack("a3a/ii/ll/ff/dd",$s);
Perl
my ($f, $s);
$f="a5ilfd";
$s=pack($f,"hello",7,7,3.14,3.14);
unpack($f,$s)
Python
import struct
f='5silfd'
s=struct.pack(f,'hello',7,7,3.14,3.14)
struct.unpack(f,s)
Ruby
f="a5ilfd"
s=["hello",7,7,3.14,3.14].pack(f)
s.unpack(f)


sprintf
PHP
$fmt = "foo: %s %d %f";
sprintf($fmt, 'bar', 13, 3.7);
Perl
my $fmt = "foo: %s %d %f";
sprintf($fmt, 'bar', 13, 3.7)
Python
'foo: %s %d %f' % ('bar',13,3.7)
# new in python 2.6:
fmt = 'foo: {0} {1} {2}'
str.format(fmt, 'bar', 13, 3.7)
Ruby
"foo: %s %d %f" % ['bar',13,3.7]


case manipulation
PHP
strtoupper("hello")
strtolower("HELLO")
ucfirst("hello")
Perl
uc("hello")
lc("HELLO")
ucfirst("hello")
Python
'hello'.upper()
'HELLO'.lower()
'hello'.capitalize()
Ruby
"hello".upcase
"HELLO".downcase
"hello".capitalize


strip
PHP
trim(" foo ")
ltrim(" foo")
rtrim("foo ")
Perl
use regex substitution
Python
' foo '.strip()
' foo'.lstrip()
'foo '.rstrip()
Ruby
" foo ".strip
" foo".lstrip
"foo ".rstrip


pad on right, on left
PHP
str_pad("hello", 10)
str_pad("hello", 10, " ",
        STR_PAD_LEFT)
Perl
sprintf("%-10s","hello")
sprintf("%10s","hello")
Python
'hello'.ljust(10)
'hello'.rjust(10)
Ruby
"hello".ljust(10)
"hello".rjust(10)


character translation
PHP
$ins = implode(range('a','z'));
$outs = substr($ins,13,13) . substr($ins,0,13);
strtr("hello",$ins,$outs)
Perl
$s = "hello";
$s =~ tr/a-z/n-za-m/;
Python
from string import lowercase as ins
from string import maketrans
outs = ins[13:] + ins[:13]
"hello".translate(maketrans(ins,outs))
Ruby
"hello".tr('a-z','n-za-m')


regexp match
PHP
preg_match('/^\d{4}$/',"1999")
preg_match('/^[a-z]+/',"foo BAR")
preg_match('/[A-Z]+/',"foo BAR")
Perl
"1999" =~ /^\d{4}$/
"foo BAR" =~ /^[a-z]+/
"foo BAR" =~ /[A-Z]+/
Python
import re
re.match("\d{4}$","1999")
re.match("[a-z]+","foo BAR")
re.search("[A-Z]+","foo BAR")
Ruby
"1999".match(/^\d{4}$/)
"foo BAR".match(/^[a-z]+/)
"foo BAR".match(/[A-Z]+/)


match, prematch, postmatch
PHP
none
Perl
my $s = "A 17 B 12";
while ( $s =~ /\d+/ ) {
  my $discard = $`;
  my $number = $&;
  $s = $';
  print $number . "\n";
}
Python
s = "A 17 B 12"
while True:
  m = re.search('\d+',s)
  if not m:
    break
  discard = s[0:m.start(0)]
  number = m.group()
  s = s[m.end(0):len(s)]
  print(s)
Ruby
s = "A 17 B 12"
while (/\d+/.match(s)) do
  discard = $`
  number = $&
  s = $'
  puts number
end


substring matches
PHP
$a = array();
$s = "2010-06-03";
$r = '/(\d{4})-(\d{2})-(\d{2})/';
preg_match($r, $s, $a);
list($_, $yr, $mn, $dy) = $a;
Perl
"2010-06-03" =~ /(\d{4})-(\d{2})-(\d{2})/;
($yr, $mn, $dy) = ($1, $2, $3);
Python
import re
reg = "(\d{4})-(\d{2})-(\d{2})"
m = re.search(reg, "2010-06-03")
yr,mn,dy = m.groups()
Ruby
reg = /(\d{4})-(\d{2})-(\d{2})/
m = reg.match("2010-06-03")
yr,mn,dy = m[1..3]


single substitution
PHP
$s = 'foo bar bar';
preg_replace('/bar/','baz',$s,1);
Perl
$s = "foo bar bar";
$s =~ s/bar/baz/;
$s
Python
import re
s = 'foo bar bar'
re.compile('bar').sub('baz', s, 1)
Ruby
"foo bar bar".sub(/bar/,'baz')


global substitution
PHP
$s = 'foo bar bar';
preg_replace('/bar/', 'baz', $s);
Perl
$s = "foo bar bar";
$s =~ s/bar/baz/g;
$s
Python
import re
s = 'foo bar bar'
re.compile('bar').sub('baz', s)
Ruby
"foo bar bar".gsub(/bar/,'baz')


containers

array literal
PHP
$nums = array(1,2,3,4);
Perl
@nums = (1,2,3,4);
Python
nums = [1,2,3,4]
Ruby
nums = [1,2,3,4]


array size
PHP
count($nums)
Perl
$#nums + 1 or
scalar(@nums)
Python
len(nums)
Ruby
nums.size
nums.length # same as size


array lookup
PHP
$nums[0]
Perl
$nums[0]
Python
nums[0]
Ruby
nums[0]


index of array element
PHP
array_search(2, array(1,2,3))
Perl
none
Python
[1,2,3].index(2)
Ruby
[1,2,3].index(2)


array slice
PHP
# 3rd arg is length of slice:
array_slice($nums,1,2)
Perl
@nums[1..2]
Python
nums[1:3]
Ruby
nums[1..2]


manipulate back of array
PHP
$a = array(6,7,8);
array_push($a, 9);
array_pop($a);
Perl
@a = (6,7,8);
push @a, 9;
pop @a;
Python
a = [6,7,8]
a.append(9)
a.pop()
Ruby
a = [6,7,8]
a.push(9)
a << 9 # same as push
a.pop


manipulate front of array
PHP
$a = array(6,7,8);
array_unshift($a, 5);
array_shift($a);
Perl
@a = (6,7,8);
unshift @a, 5;
shift @a;
Python
a = [6,7,8]
a.insert(0,5)
a.pop(0)
Ruby
a = [6,7,8]
a.unshift(5)
a.shift


array concatenation
PHP
$a = array(1,2,3);
$b = array_merge($a,array(4,5,6));
$a = array_merge($a,array(4,5,6));
Perl
@a = (1,2,3);
@b = (@a,(4,5,6));
push @a, (4,5,6);
Python
a = [1,2,3]
b = a + [4,5,6]
a.extend([4,5,6])
Ruby
a = [1,2,3]
b = a + [4,5,6]
a.concat([4,5,6])


address copy, shallow copy, deep copy
PHP
$a = (1,2,array(3,4));
$b =& $a;
none
$d = $a;
Perl
@a = (1,2,[3,4]);
$b = \@a;
@c = @a;
none
Python
a = [1,2,[3,4]]
b = a
c = list(a)
import copy
d = copy.deepcopy(a)
Ruby
a = [1,2,[3,4]]
b = a
c = a.dup
d = Marshal.load(Marshal.dump(a))


arrays as function arguments
PHP
parameter contains deep copy
Perl
each element passed as separate argument; use reference to pass array as single argument
Python
parameter contains address copy
Ruby
parameter contains address copy


array iteration
PHP
foreach (array(1,2,3) as $i) {
  echo "$i\n";
}
Perl
for $i (1 2 3) { print "$i\n" }
Python
for i in [1,2,3]:
  print(i)
Ruby
[1,2,3].each { |i| puts i }


indexed array iteration
PHP
$a = array('a','b','c');
foreach ($a as $i => $c) {
  echo "$c at index $i\n";
}
Perl
@a = ('a','b','c');
for ($i=0; $i<scalar(@a); $i++) {
  print "$a[$i] at index $i\n";
};
Python
for i, c in enumerate(['a','b','c']):
  print("%s at index %d" % (c, i))
Ruby
a = ['a','b','c']
a.each_with_index do |c,i|
  puts "#{c} at index #{i}"
end


sort
PHP
$a = array(3,1,4,2);
none
sort($a);
Perl
@a = (3,1,4,2);
sort @a;
@a = sort @a;
sort { $a <=> $b } @a;
Python
a = [3,1,4,2]
sorted(a)
a.sort()
Ruby
a = [3,1,4,2]
a.sort
a.sort!
a.sort { |m,n| m <=> n}


reverse
PHP
$a = array(1,2,3);
array_reverse($a);
$a = array_reverse($a);
Perl
@a = (1,2,3);
reverse @a;
@a = reverse @a;
Python
a = [1,2,3]
list(reversed([1,2,3]))
a.reverse()
Ruby
a = [1,2,3]
a.reverse
a.reverse!


membership
PHP
in_array(7, $nums)
Perl
grep { 7 == $_ } @nums
Python
7 in nums
Ruby
nums.include?(7)


intersection
PHP
$a = array(1,2);
$b = array(2,3,4)
array_intersect($a, $b)
Perl
Python
set.intersection(set([1,2]),
  set([2,3,4]))
Ruby
[1,2] & [2,3,4]


union
PHP
Perl
Python
set.union(set([1,2]),set([2,3,4]))
Ruby
[1,2] | [2,3,4]


map
PHP
$t2 = create_function('$x', 'return $x*$x;')
array_map($t2, array(1,2,3))
Perl
map { $_ * $_ } (1,2,3)
Python
map(lambda x: x * x, [1,2,3])
# or use list comprehension:
[x*x for x in [1,2,3]]
Ruby
[1,2,3].map { |o| o*o }


filter
PHP
$gt1 = create_function('$x','return $x>1;');
array_filter( array(1,2,3), $gt1)
Perl
grep { $_ > 1 } (1,2,3)
Python
filter(lambda x: x > 1,[1,2,3])
# or use list comprehension:
[x for x in [1,2,3] if x > 1]
Ruby
[1,2,3].select { |o| o > 1 }


reduce
PHP
$add = create_function('$a,$b','return $a+$b;');
array_reduce(array(1,2,3),$add,0)
Perl
reduce { $a + $b } 0, (1,2,3)
Python
# import needed in python 3 only
import reduce from functools
reduce(lambda x,y:x+y,[1,2,3],0)
Ruby
[1,2,3].inject(0) { |m,o| m+o }


universal test
PHP
none, use array_filter
Perl
none, use grep
Python
all(i%2 == 0 for i in [1,2,3,4])
Ruby
[1,2,3,4].all? {|i| i.even? }


existential test
PHP
none, use array_filter
Perl
none, use grep
Python
any(i%2 == 0 for i in [1,2,3,4])
Ruby
[1,2,3,4].any? {|i| i.even? }


dictionary literal
PHP
$h = array('t' => 1, 'f' => 0);
Perl
%h = ( 't' => 1, 'f' => 0 );
Python
h = { 't':1, 'f':0 }
Ruby
h = { 't' => 1, 'f' => 0 }


dictionary size
PHP
count($h)
Perl
scalar(keys %h)
Python
len(h)
Ruby
h.size
h.length # same as size


dictionary lookup
PHP
$h['t']
Perl
$h{'t'}
Python
h['t']
Ruby
h['t']


is dictionary key present
PHP
array_key_exists('y',$h);
Perl
defined($h{'y'})
Python
'y' in h
Ruby
h.has_key?('y')


dictionary iteration
PHP
foreach ($h as $k => $v ) {
Perl
while ( ($k, $v) = each %h ) {
Python
# python 2:
for k,v in h.iteritems():
  code
# python 3:
for k,v in h.items():
  code
Ruby
h.each { |k,v| code }


keys and values of dictionary as arrays
PHP
array_keys($h)
array_values($h)
Perl
keys %h
values %h
Python
h.keys()
h.values()
Ruby
h.keys
h.values


out of bounds behavior
PHP
NULL
Perl
undef
Python
raises IndexError or KeyError
Ruby
nil


functions

function declaration
PHP
function add($a, $b) { return $a + $b; }
Perl
sub add { $_[0] + $_[1] }
Python
def add(a,b): return a+b
Ruby
def add(a,b); a+b; end


function invocation
PHP
add(3,7);
Perl
add(1,2);
Python
add(1,2)
Ruby
add(1,2)


missing argument
PHP
set to NULL with warning
Perl
set to undef
Python
raises TypeError
Ruby
raises ArgumentError


default value
PHP
function my_log($x, $b=10) {
Perl
none
Python
def log(x,base=10):
Ruby
def log(x,base=10)


arbitrary number of arguments
PHP
function add() { return array_sum(func_get_args()); }
Perl
@_ contains all values
Python
def add(first,*rest):
  if not rest:
    return first
  else:
    return first+add(*rest)
Ruby
def add(first, *rest)
  if rest.empty?
    first
  else
    first + add(*rest)
  end
end


named parameter definition
PHP
none
Perl
none
Python
def f(**d):
Ruby
def f(h)


named parameter invocation
PHP
none
Perl
none
Python
f(eps=0.01)
Ruby
f(:eps => 0.01)


pass number or string by reference
PHP
function foo(&$x, &$y) {
  $x += 1;
  $y .= 'ly';
}

$n = 7;
$s = 'hard';
foo($n, $s);

Perl
sub foo {
  $_[0] += 1;
  $_[1] .= 'ly';
}

my $n = 7;
my $s = 'hard';
foo($n, $s);

Python
not possible
Ruby