<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
<link rel="icon" type="image/gif" href="favicon.gif"/>
<link rel="apple-touch-icon" sizes="120x120" href="touch-icon-iphone-retina.png" />
<link rel="apple-touch-icon" sizes="152x152" href="touch-icon-ipad-retina.png" />
<title>Scripting Languages I: Node.js, Python, PHP, Ruby - Hyperpolyglot</title>
<style type="text/css" id="internal-style">
@import url(hyperpolyglot.css);
</style>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/>
<meta http-equiv="content-language" content="en"/>
</head>
<body>
<div id="container-wrap-wrap">
  <div id="container-wrap">
    <div id="container">
      <div id="header">
        <h1><a href="index.html"><span>Hyperpolyglot</span></a></h1>
      </div>
      <div id="content-wrap">
        <div id="main-content">
<div id="page-title">
                            Scripting Languages I: Node.js, Python, PHP, Ruby
                        </div>
<div id="page-content">
                        

<p><a name="top" id="top"></a><em>a side-by-side reference sheet</em></p>
<p><strong>sheet one:</strong> <a href="scripting#version">version</a> | <a href="scripting#grammar-execution">grammar and execution</a> | <a href="scripting#var-expr">variables and expressions</a> | <a href="scripting#arithmetic-logic">arithmetic and logic</a> | <a href="scripting#strings">strings</a> | <a href="scripting#regexes">regexes</a> | <a href="scripting#dates-time">dates and time</a> | <a href="scripting#arrays">arrays</a> | <a href="scripting#dictionaries">dictionaries</a> | <a href="scripting#functions">functions</a> | <a href="scripting#execution-control">execution control</a> | <a href="scripting#exceptions">exceptions</a> | <a href="scripting#threads">threads</a></p>
<p><strong><a href="scripting2">sheet two</a>:</strong> <a href="scripting2#streams">streams</a> | <a href="scripting2#async">asynchronous events</a> | <a href="scripting2#files">files</a> | <a href="scripting2#file-fmt">file formats</a> | <a href="scripting2#directories">directories</a> | <a href="scripting2#processes-environment">processes and environment</a> | <a href="scripting2#option-parsing">option parsing</a> | <a href="scripting2#libraries-namespaces">libraries and namespaces</a> | <a href="scripting2#objects">objects</a> | <a href="scripting2#reflection">reflection</a> | <a href="scripting2#net-web">net and web</a> | <a href="scripting2#databases">databases</a> | <a href="scripting2#unit-tests">unit tests</a> | <a href="scripting2#debugging">debugging</a></p>
<table class="wiki-content-table">
<tr>
<th colspan="5"><a name="version" id="version"></a><a href="scripting#version-note">version</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="version-used" id="version-used"></a><a href="scripting#version-used-note">version used</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>6.11</em></span></td>
<td><span style="color: gray"><em>3.6</em></span></td>
<td><span style="color: gray"><em>7.0</em></span></td>
<td><span style="color: gray"><em>2.3</em></span></td>
</tr>
<tr>
<td><a name="version" id="version"></a><a href="scripting#version-note">show version</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>$ node <span style="white-space: pre-wrap;">--</span>version</td>
<td>$ python -V<br />
$ python <span style="white-space: pre-wrap;">--</span>version</td>
<td>$ php <span style="white-space: pre-wrap;">--</span>version</td>
<td>$ ruby <span style="white-space: pre-wrap;">--</span>version</td>
</tr>
<tr>
<td><a name="implicit-prologue" id="implicit-prologue"></a><a href="scripting#implicit-prologue-note">implicit prologue</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> npm install lodash</span><br />
const _ = require('lodash');</td>
<td>import os, re, sys</td>
<td><span style="color: gray"># sudo apt install php-mbstring</span></td>
<td><span style="color: gray"><em>none</em></span></td>
</tr>
<tr>
<th colspan="5"><a name="grammar-execution" id="grammar-execution"></a><a href="scripting#grammar-execution-note">grammar and execution</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="interpreter" id="interpreter"></a><a href="scripting#interpreter-note">interpreter</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>$ node foo.js</td>
<td>$ python foo.py</td>
<td>$ php -f foo.php</td>
<td>$ ruby foo.rb</td>
</tr>
<tr>
<td><a name="repl" id="repl"></a><a href="scripting#repl-note">repl</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>$ node</td>
<td>$ python</td>
<td>$ php -a</td>
<td>$ irb</td>
</tr>
<tr>
<td><a name="cmd-line-program" id="cmd-line-program"></a><a href="scripting#cmd-line-program-note">command line program</a></td>
<td>$ node -e "console.log('hi!');"</td>
<td>$ python -c 'print("hi!")'</td>
<td>$ php -r 'echo "hi!\n";'</td>
<td>$ ruby -e 'puts "hi!"'</td>
</tr>
<tr>
<td><a name="block-delimiters" id="block-delimiters"></a><a href="scripting#block-delimiters-note">block delimiters</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>{}</td>
<td>: <span style="color: gray"><em>and offside rule</em></span></td>
<td>{}</td>
<td>{}<br />
do end</td>
</tr>
<tr>
<td><a name="statement-separator" id="statement-separator"></a><a href="scripting#statement-separator-note">statement separator</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>; or newline<br />
<br />
newline not separator inside (), [], {}, "", '', or after binary operator<br />
<br />
newline sometimes not separator when following line would not parse as a valid statement</em></span></td>
<td><span style="color: gray"><em>newline or</em></span> ;<br />
<br />
<span style="color: gray"><em>newlines not separators inside (), [], {}, triple quote literals, or after backslash: <span style="white-space: pre-wrap;">\</span></em></span></td>
<td>;<br />
<br />
<span style="color: gray"><em>statements must be semicolon terminated inside {}</em></span></td>
<td><span style="color: gray"><em>newline or</em></span> ;<br />
<br />
<span style="color: gray"><em>newlines not separators inside (), [], {}, <span style="white-space: pre-wrap;">``</span>, '', "", or after binary operator or backslash: <span style="white-space: pre-wrap;">\</span></em></span></td>
</tr>
<tr>
<td><a name="source-code-encoding" id="source-code-encoding"></a><a href="scripting#source-code-encoding-note">source code encoding</a></td>
<td><span style="color: gray"><em>source is always UTF-8</em></span></td>
<td><span style="color: gray"><em>Python 3 source is UTF-8 by default; Python 2 source is US-ASCII</em></span><br />
<br />
<span style="color: gray"># -*- coding: us-ascii -*-</span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>Ruby 2.0 source is UTF-8 by default</em></span><br />
<br />
<span style="color: gray"># -*- coding: utf-8 -*-</span></td>
</tr>
<tr>
<td><a name="eol-comment" id="eol-comment"></a><a href="scripting#eol-comment-note">end-of-line comment</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> comment</span></td>
<td><span style="color: gray"># comment</span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> comment<br />
# comment</span></td>
<td><span style="color: gray"># comment</span></td>
</tr>
<tr>
<td><a name="multiple-line-comment" id="multiple-line-comment"></a><a href="scripting#multiple-line-comment-note">multiple line comment</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray">/* line<br />
another line */</span></td>
<td><span style="color: gray"><em>use triple quote string literal:</em></span><br />
<br />
'''comment line<br />
another line'''</td>
<td><span style="color: gray">/* comment line<br />
another line */</span></td>
<td><span style="color: gray">=begin<br />
comment line<br />
another line<br />
=end</span></td>
</tr>
<tr>
<th colspan="5"><a name="var-expr" id="var-expr"></a><a href="scripting#var-expr-note">variables and expressions</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="local-var" id="local-var"></a><a href="scripting#local-var-note">local variable</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> new in ES6:</span><br />
let x = 1;<br />
let y = 2, z = 3;<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> older alternative to let:</span><br />
var x = 1;<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> let local scope is nearest<br />
<span style="white-space: pre-wrap;">//</span> enclosing block; var local scope<br />
<span style="white-space: pre-wrap;">//</span> is nearest function body.<br />
<br />
<span style="white-space: pre-wrap;">//</span> var variables are visible to all code<br />
<span style="white-space: pre-wrap;">//</span> in the function body; even code<br />
<span style="white-space: pre-wrap;">//</span> preceding the var statement.</span></td>
<td><span style="color: gray"># in function body:</span><br />
x = 1<br />
y, z = 2, 3</td>
<td><span style="color: gray"># in function body:</span><br />
$x = 1;<br />
list($y, $z) = [2, 3];</td>
<td>x = 1<br />
y, z = 2, 3</td>
</tr>
<tr>
<td><a name="file-scope-var" id="file-scope-var"></a><a href="scripting#file-scope-var-note">file scope variable</a></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> outside any function body:</span><br />
let n = 1;<br />
<br />
incrFileVar () { n++; }</td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
</tr>
<tr>
<td><a name="global-var" id="global-var"></a><a href="scripting#global-var-note">global variable</a></td>
<td>global.g = 1;<br />
<br />
incrGlobal () { global.g++; }</td>
<td>g = 1<br />
<br />
def incr_global():<br />
<span style="white-space: pre-wrap;">  </span>global g<br />
<span style="white-space: pre-wrap;">  </span>g += 1</td>
<td>$g = 1;<br />
<br />
function incr_global() {<br />
<span style="white-space: pre-wrap;">  </span>global $g;<br />
<span style="white-space: pre-wrap;">  </span>++$g;<br />
}</td>
<td>$g = 1<br />
<br />
def incr_global<br />
<span style="white-space: pre-wrap;">  </span>$g += 1<br />
end</td>
</tr>
<tr>
<td><a name="const" id="const"></a><a href="scripting#const-note">constant</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> new in ES6</span><br />
const PI = 3.14;</td>
<td><span style="color: gray"># uppercase identifiers<br />
# constant by convention</span><br />
PI = 3.14</td>
<td>define("PI", 3.14);<br />
<br />
const PI = 3.14;</td>
<td><span style="color: gray"># warning if capitalized<br />
# identifier is reassigned</span><br />
PI = 3.14</td>
</tr>
<tr>
<td><a name="assignment" id="assignment"></a><a href="scripting#assignment-note">assignment</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>v = 1;</td>
<td><span style="color: gray"># assignments can be chained<br />
# but otherwise don't return values:</span><br />
v = 1</td>
<td>$v = 1;</td>
<td>v = 1</td>
</tr>
<tr>
<td><a name="parallel-assignment" id="parallel-assignment"></a><a href="scripting#parallel-assignment-note">parallel assignment</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> new in ES6:</span><br />
let [x, y, z] = [1, 2, 3];</td>
<td>x, y, z = 1, 2, 3<br />
<br />
<span style="color: gray"># raises ValueError:</span><br />
x, y = 1, 2, 3<br />
<br />
<span style="color: gray"># raises ValueError:</span><br />
x, y, z = 1, 2</td>
<td>list($x, $y, $z) = [1 ,2, 3];<br />
<br />
<span style="color: gray"># 3 is discarded:</span><br />
list($x, $y) = [1, 2, 3];<br />
<br />
<span style="color: gray"># $z set to NULL:</span><br />
list($x, $y, $z) = [1, 2];</td>
<td>x, y, z = 1, 2, 3<br />
<br />
<span style="color: gray"># 3 is discarded:</span><br />
x, y = 1, 2, 3<br />
<br />
<span style="color: gray"># z set to nil:</span><br />
x, y, z = 1, 2</td>
</tr>
<tr>
<td><a name="swap" id="swap"></a><a href="scripting#swap-note">swap</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> new in ES6:</span><br />
[x, y] = [y, x];</td>
<td>x, y = y, x</td>
<td>list($x, $y) = [$y, $x];</td>
<td>x, y = y, x</td>
</tr>
<tr>
<td><a name="compound-assignment" id="compound-assignment"></a><a href="scripting#compound-assignment-note">compound assignment</a><br />
<span style="color: gray"><em>arithmetic, string, logical, bit</em></span></td>
<td>+= -= *= /= <span style="color: gray"><em>none</em></span> %=<br />
+=<br />
<span style="color: gray"><em>none</em></span><br />
<span style="white-space: pre-wrap;">&lt;&lt;= &gt;&gt;= </span>&amp;= |= ^=</td>
<td><span style="color: gray"># do not return values:</span><br />
+= -= *= /= <span style="white-space: pre-wrap;">//</span>= %= <span style="white-space: pre-wrap;">**</span>=<br />
+= *=<br />
&amp;= <span style="white-space: pre-wrap;">|</span>= ^=<br />
<span style="white-space: pre-wrap;">&lt;&lt;= &gt;&gt;= </span>&amp;= |= ^=</td>
<td>+= -= *= <span style="color: gray"><em>none</em></span> /= %= <span style="white-space: pre-wrap;">**</span>=<br />
.= <span style="color: gray"><em>none</em></span><br />
&amp;= |= <span style="color: gray"><em>none</em></span><br />
<span style="white-space: pre-wrap;">&lt;&lt;= &gt;&gt;= </span>&amp;= |= ^=</td>
<td>+= -= *= /= <span style="color: gray"><em>none</em></span> %= <span style="white-space: pre-wrap;">**</span>=<br />
+= *=<br />
&amp;&amp;= <span style="white-space: pre-wrap;">||</span>= ^=<br />
<span style="white-space: pre-wrap;">&lt;&lt;= &gt;&gt;= </span>&amp;= |= ^=</td>
</tr>
<tr>
<td><a name="incr-decr" id="incr-decr"></a><a href="scripting#incr-decr-note">increment and decrement</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>let x = 1;<br />
let y = ++x;<br />
let z = <span style="white-space: pre-wrap;">--</span>y;</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>$x = 1;<br />
$y = ++$x;<br />
$z = <span style="white-space: pre-wrap;">--</span>$y;</td>
<td>x = 1<br />
<span style="color: gray"># x and y not mutated:</span><br />
y = x.succ<br />
z = y.pred</td>
</tr>
<tr>
<td><a name="null" id="null"></a><a href="scripting#null-note">null</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>null</td>
<td>None</td>
<td>NULL <span style="color: gray"># case insensitive</span></td>
<td>nil</td>
</tr>
<tr>
<td><a name="null-test" id="null-test"></a><a href="scripting#null-test-note">null test</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>v === null</td>
<td>v is None</td>
<td>is_null($v)<br />
! isset($v)</td>
<td>v == nil<br />
v.nil?</td>
</tr>
<tr>
<td><a name="undef-var" id="undef-var"></a><a href="scripting#undef-var-note">undefined variable</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>Evaluates as</em></span> undefined<br />
<br />
<span style="color: gray"><em>Use the triple equality</em></span> === <span style="color: gray"><em>operator to test for this value.</em></span></td>
<td><span style="color: gray"><em>raises</em></span> NameError</td>
<td><span style="color: gray"><em>Evaluates as</em></span> NULL</td>
<td><span style="color: gray"><em>raises</em></span> NameError</td>
</tr>
<tr>
<td><a name="conditional-expr" id="conditional-expr"></a><a href="scripting#conditional-expr-note">conditional expression</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>x &gt; 0 ? x : -x</td>
<td>x if x &gt; 0 else -x</td>
<td>$x &gt; 0 ? $x : -$x</td>
<td>x &gt; 0 ? x : -x</td>
</tr>
<tr>
<th colspan="5"><a name="arithmetic-logic" id="arithmetic-logic"></a><a href="scripting#arithmetic-logic-note">arithmetic and logic</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="true-false" id="true-false"></a><a href="scripting#true-false-note">true and false</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>true false</td>
<td>True False</td>
<td>TRUE FALSE <span style="color: gray"># case insensitive</span></td>
<td>true false</td>
</tr>
<tr>
<td><a name="falsehoods" id="falsehoods"></a><a href="scripting#falsehoods-note">falsehoods</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>false null undefined '' 0 NaN</td>
<td>False None 0 0.0 '' [] {}</td>
<td>FALSE NULL 0 0.0 "" "0" []</td>
<td>false nil</td>
</tr>
<tr>
<td><a name="logical-op" id="logical-op"></a><a href="scripting#logical-op-note">logical operators</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="white-space: pre-wrap;">&amp;&amp; ||</span> !</td>
<td>and or not</td>
<td>&amp;&amp; <span style="white-space: pre-wrap;">||</span> !<br />
<span style="color: gray"><em>lower precedence:</em></span><br />
and or xor</td>
<td>&amp;&amp; <span style="white-space: pre-wrap;">||</span> !<br />
<span style="color: gray"><em>lower precedence:</em></span><br />
and or not</td>
</tr>
<tr>
<td><a name="relational-op" id="relational-op"></a><a href="scripting#relational-op-note">relational operators</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="white-space: pre-wrap;">===</span> !== &lt; &gt; &gt;= &lt;=<br />
<br />
<span style="color: gray"><em>perform type coercion:</em></span><br />
<span style="white-space: pre-wrap;">==</span> !=</td>
<td><span style="color: gray"><em>relational operators are chainable:</em></span><br />
== != &gt; &lt; &gt;= &lt;=</td>
<td>== != <span style="color: gray"><em>or</em></span> &lt;&gt; &gt; &lt; &gt;= &lt;=<br />
<span style="color: gray"><em>no conversion:</em></span> === !==</td>
<td>== != &gt; &lt; &gt;= &lt;=</td>
</tr>
<tr>
<td><a name="min-max" id="min-max"></a><a href="scripting#min-max-note">min and max</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>Math.min(1, 2, 3)<br />
Math.max(1, 2, 3)<br />
<br />
Math.min.apply(Math, [1, 2, 3])<br />
Math.max.apply(Math, [1, 2, 3])</td>
<td>min(1, 2, 3)<br />
max(1, 2, 3)<br />
<br />
min([1, 2, 3])<br />
max([1, 2, 3])</td>
<td>min(1, 2, 3)<br />
max(1, 2, 3)<br />
$a = [1, 2, 3]<br />
min($a)<br />
max($a)</td>
<td>[1, 2, 3].min<br />
[1, 2, 3].max</td>
</tr>
<tr>
<td><a name="arith-op" id="arith-op"></a><a href="scripting#arith-op-note">arithmetic operators</a><br />
<span style="color: gray"><em>addition, subtraction, multiplication, float division, quotient, remainder</em></span></td>
<td>+ - * / <span style="color: gray"><em>none</em></span> %</td>
<td>+ - * / // %<br />
<br />
<span style="color: gray"><em>In Python 2, / performs integer division.</em></span></td>
<td>+ - * / <span style="color: gray"><em>none</em></span> %</td>
<td>+ - * x.fdiv(y) / %</td>
</tr>
<tr>
<td><a name="int-div" id="int-div"></a><a href="scripting#int-div-note">integer division</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>Math.floor(22 / 7)</td>
<td>22 // 7</td>
<td>(int)(22 / 7)</td>
<td>22 / 7</td>
</tr>
<tr>
<td><a name="divmod" id="divmod"></a><a href="scripting#divmod-note">divmod</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>q, r = divmod(22, 7)</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>q, r = 22.divmod(7)</td>
</tr>
<tr>
<td><a name="int-div-zero" id="int-div-zero"></a><a href="scripting#int-div-zero-note">integer division by zero</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>Returns Infinity, NaN, or -Infinity depending upon sign of dividend.<br />
<br />
There are literals for Infinity and NaN.</em></span></td>
<td><span style="color: gray"><em>raises</em> ZeroDivisionError</span></td>
<td><span style="color: gray"><em>returns</em> FALSE <em>with warning</em></span></td>
<td><span style="color: gray"><em>raises</em> ZeroDivisionError</span></td>
</tr>
<tr>
<td><a name="float-div" id="float-div"></a><a href="scripting#float-div-note">float division</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>22 / 7</td>
<td>22 / 7<br />
<br />
<span style="color: gray"># Python 2:</span><br />
float(22) / 7</td>
<td>22 / 7</td>
<td>22.to_f / 7<br />
<br />
22.fdiv(7)</td>
</tr>
<tr>
<td><a name="float-div-zero" id="float-div-zero"></a><a href="scripting#float-div-zero-note">float division by zero</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>same behavior as for integers</em></span></td>
<td><span style="color: gray"><em>raises</em> ZeroDivisionError</span></td>
<td><span style="color: gray"><em>returns</em> FALSE <em>with warning</em></span></td>
<td><span style="color: gray"><em>returns</em> -Infinity, NaN, <em>or</em> Infinity</span></td>
</tr>
<tr>
<td><a name="power" id="power"></a><a href="scripting#power-note">power</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>Math.pow(2, 32)</td>
<td>2 <span style="white-space: pre-wrap;">**</span> 32</td>
<td>pow(2, 32)</td>
<td>2 <span style="white-space: pre-wrap;">**</span> 32</td>
</tr>
<tr>
<td><a name="sqrt" id="sqrt"></a><a href="scripting#sqrt-note">sqrt</a></td>
<td>Math.sqrt(2)</td>
<td>import math<br />
<br />
math.sqrt(2)</td>
<td>sqrt(2)</td>
<td>include Math<br />
<br />
sqrt(2)</td>
</tr>
<tr>
<td><a name="sqrt-negative-one" id="sqrt-negative-one"></a><a href="scripting#sqrt-negative-one-note">sqrt -1</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>NaN</td>
<td><span style="color: gray"># raises ValueError:</span><br />
import math<br />
math.sqrt(-1)<br />
<br />
<span style="color: gray"># returns complex float:</span><br />
import cmath<br />
cmath.sqrt(-1)</td>
<td>NaN</td>
<td><span style="color: gray">Math.sqrt(-1) raises Math::DomainError unless require 'complex' is in effect.</span><br />
<br />
<span style="color: gray">(-1) ** 0.5 is (0+1.0i)</span></td>
</tr>
<tr>
<td><a name="transcendental-func" id="transcendental-func"></a><a href="scripting#transcendental-func-note">transcendental functions</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>Math.exp Math.log Math.sin Math.cos Math.tan Math.asin Math.acos Math.atan Math.atan2</td>
<td>from math import exp, log, \<br />
sin, cos, tan, asin, acos, atan, atan2</td>
<td>exp log sin cos tan asin acos atan atan2</td>
<td>include Math<br />
<br />
exp log sin cos tan asin acos atan atan2</td>
</tr>
<tr>
<td><a name="transcendental-const" id="transcendental-const"></a><a href="scripting#transcendental-const-note">transcendental constants</a><br />
<span style="color: gray"><em>π and e</em></span></td>
<td>Math.PI<br />
Math.E</td>
<td>import math<br />
<br />
math.pi math.e</td>
<td>M_PI M_E</td>
<td>include Math<br />
<br />
PI E</td>
</tr>
<tr>
<td><a name="float-truncation" id="float-truncation"></a><a href="scripting#float-truncation-note">float truncation</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span><br />
Math.round(3.1)<br />
Math.floor(3.1)<br />
Math.ceil(3.1)</td>
<td>import math<br />
<br />
int(x)<br />
int(round(x))<br />
math.ceil(x)<br />
math.floor(x)</td>
<td>(int)$x<br />
round($x)<br />
ceil($x)<br />
floor($x)</td>
<td>x.to_i<br />
x.round<br />
x.ceil<br />
x.floor</td>
</tr>
<tr>
<td><a name="abs-val" id="abs-val"></a><a href="scripting#abs-val-note">absolute value</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>Math.abs(-3)</td>
<td>abs(x)</td>
<td>abs($x)</td>
<td>x.abs</td>
</tr>
<tr>
<td><a name="int-overflow" id="int-overflow"></a><a href="scripting#int-overflow-note">integer overflow</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>all numbers are floats</em></span></td>
<td><span style="color: gray"><em>becomes arbitrary length integer of type</em> long</span></td>
<td><span style="color: gray"><em>converted to float</em></span></td>
<td><span style="color: gray"><em>becomes arbitrary length integer of type</em> Bignum</span></td>
</tr>
<tr>
<td><a name="float-overflow" id="float-overflow"></a><a href="scripting#float-overflow-note">float overflow</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>Infinity</td>
<td><span style="color: gray"><em>raises</em> OverflowError</span></td>
<td>INF</td>
<td>Infinity</td>
</tr>
<tr>
<td><a name="rational-construction" id="rational-construction"></a><a href="scripting#rational-construction-note">rational construction</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>from fractions import Fraction<br />
<br />
x = Fraction(22, 7)</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>22 / 7r<br />
22r / 7</td>
</tr>
<tr>
<td><a name="rational-decomposition" id="rational-decomposition"></a><a href="scripting#rational-decomposition-note">rational decomposition</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>x.numerator<br />
x.denominator</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>(22 / 7r).numerator<br />
(22 / 7r).denominator</td>
</tr>
<tr>
<td><a name="complex-construction" id="complex-construction"></a><a href="scripting#complex-construction-note">complex construction</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>z = 1 + 1.414j</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>z = 1 + 1.414i</td>
</tr>
<tr>
<td><a name="complex-decomposition" id="complex-decomposition"></a><a href="scripting#complex-decomposition-note">complex decomposition</a><br />
<span style="color: gray"><em>real and imaginary component, argument, absolute value, conjugate</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>import cmath<br />
<br />
z.real<br />
z.imag<br />
cmath.phase(z)<br />
abs(z)<br />
z.conjugate()</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>(1 + 3i).real<br />
(1 + 3i).imag<br />
(1 + 3i).arg<br />
(1 + 3i).abs<br />
(1 + 3i).conj</td>
</tr>
<tr>
<td><a name="random-num" id="random-num"></a><a href="scripting#random-num-note">random number</a><br />
<span style="color: gray"><em>uniform integer, uniform float, normal float</em></span></td>
<td>Math.floor(Math.random() * 100)<br />
Math.random()<br />
<span style="color: gray"><em>none</em></span></td>
<td>import random<br />
<br />
random.randint(0, 99)<br />
random.random()<br />
random.gauss(0, 1)</td>
<td>rand(0,99)<br />
lcg_value()<br />
<span style="color: gray"><em>none</em></span></td>
<td>rand(100)<br />
rand<br />
<span style="color: gray"><em>none</em></span></td>
</tr>
<tr>
<td><a name="random-seed" id="random-seed"></a><a href="scripting#random-seed-note">random seed</a><br />
<span style="color: gray"><em>set, get, restore</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>import random<br />
<br />
random.seed(17)<br />
seed = random.getstate()<br />
random.setstate(seed)</td>
<td>srand(17);<br />
<br />
<span style="color: gray"><em>none</em></span></td>
<td>srand(17)<br />
<br />
seed = srand<br />
srand(seed)</td>
</tr>
<tr>
<td><a name="bit-op" id="bit-op"></a><a href="scripting#bit-op-note">bit operators</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="white-space: pre-wrap;">&lt;&lt; &gt;&gt; &amp; | ^ ~</span></td>
<td><span style="white-space: pre-wrap;">&lt;&lt; &gt;&gt; &amp; | ^ ~</span></td>
<td><span style="white-space: pre-wrap;">&lt;&lt; &gt;&gt; &amp; | ^ ~</span></td>
<td><span style="white-space: pre-wrap;">&lt;&lt; &gt;&gt; &amp; | ^ ~</span></td>
</tr>
<tr>
<td><a name="binary-octal-hex-literals" id="binary-octal-hex-literals"></a><a href="scripting#binary-octal-hex-literals-note">binary, octal, and hex literals</a></td>
<td><span style="color: gray"><em>none</em></span><br />
052 <span style="color: gray"><span style="white-space: pre-wrap;">//</span> deprecated</span><br />
0x2a</td>
<td>0b101010<br />
0o52<span style="white-space: pre-wrap;">  </span><span style="color: gray"><span style="white-space: pre-wrap;">#</span> also 052 in Python 2</span><br />
0x2a</td>
<td>0b101010<br />
052<br />
0x2a</td>
<td>0b101010<br />
052<br />
0x2a</td>
</tr>
<tr>
<td><a name="radix" id="radix"></a><a href="scripting#radix-note">radix</a><br />
<span style="color: gray"><em>convert integer to and from string with radix</em></span></td>
<td>(42).toString(7)<br />
parseInt('60', 7)</td>
<td><span style="color: gray"><em>none</em></span><br />
int('60', 7)</td>
<td>base_convert("42", 10, 7);<br />
base_convert("60", 7, 10);</td>
<td>42.to_s(7)<br />
"60".to_i(7)</td>
</tr>
<tr>
<th colspan="5"><a name="strings" id="strings"></a><a href="scripting#strings-note">strings</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="str-type" id="str-type"></a><a href="scripting#str-type-note">string type</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>String</td>
<td>str<br />
<br />
<span style="color: gray"># Python 2:</span><br />
unicode</td>
<td><span style="color: gray"># array of bytes:</span><br />
string</td>
<td>String</td>
</tr>
<tr>
<td><a name="str-literal" id="str-literal"></a><a href="scripting#str-literal-note">string literal</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>'don\'t say "no"'<br />
"don't say \"no\""</td>
<td>'don\'t say "no"'<br />
"don't say \"no\""<br />
"don't " 'say "no"'<br />
<br />
<span style="color: gray"># Python 2 (and Python 3):</span><br />
u'lorem'<br />
u"ipsum"</td>
<td>"don't say \"no\""<br />
'don\'t say "no"'</td>
<td>"don't say \"no\""<br />
'don\'t say "no"'<br />
"don't " 'say "no"'</td>
</tr>
<tr>
<td><a name="newline-in-str-literal" id="newline-in-str-literal"></a><a href="scripting#newline-in-str-literal-note">newline in literal</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> backquote literals only:</span><br />
<span style="white-space: pre-wrap;">`</span>first line<br />
second line<span style="white-space: pre-wrap;">`</span><br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> Backslashes can be used to break<br />
<span style="white-space: pre-wrap;">//</span> long strings.</span></td>
<td><span style="color: gray"># triple quote literals only:</span><br />
'''first line<br />
second line'''<br />
<br />
"""first line<br />
second line"""</td>
<td>'first line<br />
second line'<br />
<br />
"first line<br />
second line"</td>
<td>'first line<br />
second line'<br />
<br />
"first line<br />
second line"</td>
</tr>
<tr>
<td><a name="str-literal-esc" id="str-literal-esc"></a><a href="scripting#str-literal-esc-note">literal escapes</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>single and double quotes:</em></span><br />
\b \f \n \r \t \v \x<span style="color: gray"><em>hh</em></span> \" \' \\<br />
\u<span style="color: gray"><em>hhhh</em></span> \u{<span style="color: gray"><em>hhhhh</em></span>}</td>
<td>\<span style="color: gray"><em>newline</em></span> \\ \' \" \a \b \f \n \r \t \v \<span style="color: gray"><em>ooo</em></span> \x<span style="color: gray"><em>hh</em></span> \u<span style="color: gray"><em>hhhh</em></span> \U<span style="color: gray"><em>hhhhhhhh</em></span><br />
<br />
<span style="color: gray"><em>In Python 2,</em> \u <em>and</em> \U <em>only available in string literals with</em> u <em>prefix</em></span></td>
<td><span style="color: gray"><em>double quoted:</em></span><br />
\f \n \r \t \v \x<span style="color: gray"><em>hh</em></span> \$ \" \\ \<span style="color: gray"><em>ooo</em></span><br />
<br />
<span style="color: gray"><em>single quoted:</em></span><br />
\' \\</td>
<td><span style="color: gray"><em>double quoted:</em></span><br />
\a \b \c<span style="color: gray"><em>x</em></span> \e \f \n \r \s \t \v \x<span style="color: gray"><em>hh</em></span> \<span style="color: gray"><em>ooo</em></span> \u<span style="color: gray"><em>hhhh</em></span> \u{<span style="color: gray"><em>hhhhh</em></span>}<br />
<br />
<span style="color: gray"><em>single quoted:</em></span><br />
\' \\</td>
</tr>
<tr>
<td><a name="here-doc" id="here-doc"></a><a href="scripting#here-doc-note">here document</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>$word = "amet";<br />
<br />
$s = <span style="white-space: pre-wrap;">&lt;&lt;&lt;</span>EOF<br />
lorem ipsum<br />
dolor sit $word<br />
EOF;</td>
<td>word = "amet"<br />
<br />
s = <span style="white-space: pre-wrap;">&lt;&lt;</span>EOF<br />
lorem ipsum<br />
dolor sit #{word}<br />
EOF</td>
</tr>
<tr>
<td><a name="var-interpolation" id="var-interpolation"></a><a href="scripting#var-interpolation-note">variable interpolation</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>let count = 3;<br />
let item = 'ball';<br />
let s = <span style="white-space: pre-wrap;">`</span>${count} ${item}s<span style="white-space: pre-wrap;">`</span>;</td>
<td>count = 3<br />
item = 'ball'<br />
print('{count} {item}s'.format(<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">**</span>locals()))<br />
<br />
<span style="color: gray"># Python 3.6:</span><br />
print(f'{count} {item}s')</td>
<td>$count = 3;<br />
$item = "ball";<br />
echo "$count ${item}s\n";</td>
<td>count = 3<br />
item = "ball"<br />
puts "#{count} #{item}s"</td>
</tr>
<tr>
<td><a name="expr-interpolation" id="expr-interpolation"></a><a href="scripting#expr-interpolation-note">expression interpolation</a></td>
<td><span style="white-space: pre-wrap;">`</span>1 + 1 = ${1 + 1}<span style="white-space: pre-wrap;">`</span></td>
<td>'1 + 1 = {}'.format(1 + 1)<br />
<br />
<span style="color: gray"># Python 3.6:</span><br />
f'1 + 1 = {1 + 1}'</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>"1 + 1 = #{1 + 1}"</td>
</tr>
<tr>
<td><a name="format-str" id="format-str"></a><a href="scripting#format-str-note">format string</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> None; use string concatenation.<br />
<span style="white-space: pre-wrap;">//</span> Evaluates to "12.35":</span><br />
12.3456.toFixed(2)</td>
<td>'lorem %s %d %f' % ('ipsum', 13, 3.7)<br />
<br />
fmt = 'lorem {0} {1} {2}'<br />
fmt.format('ipsum', 13, 3.7)</td>
<td>$fmt = "lorem %s %d %f";<br />
sprintf($fmt, "ipsum", 13, 3.7);</td>
<td>"lorem %s %d %f" % ["ipsum", 13, 3.7]</td>
</tr>
<tr>
<td><a name="mutable-str" id="mutable-str"></a><a href="scripting#mutable-str-note">are strings mutable?</a></td>
<td><span style="color: gray"><em>no</em></span></td>
<td><span style="color: gray"><em>no</em></span></td>
<td>$s = "bar";<br />
$s2 = $s;<br />
<span style="color: gray"># sets s to "baz"; s2 is unchanged:</span><br />
$s[2] = "z";</td>
<td>s = "bar"<br />
s2 = s<br />
<span style="color: gray"># sets s and s2 to "baz":</span><br />
s[2] = "z"</td>
</tr>
<tr>
<td><a name="copy-str" id="copy-str"></a><a href="scripting#copy-str-note">copy string</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>$s2 = $s;</td>
<td>s = "bar"<br />
s2 = s.clone<br />
<span style="color: gray"># s2 is not altered:</span><br />
s[2] = "z"</td>
</tr>
<tr>
<td><a name="str-concat" id="str-concat"></a><a href="scripting#str-concat-note">concatenate</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>s = 'Hello, ' + 'World!';</td>
<td>s = 'Hello, '<br />
s2 = s + 'World!'<br />
<br />
<span style="color: gray"># juxtaposition can be used to<br />
# concatenate literals:</span><br />
s2 = 'Hello, ' "World!"</td>
<td>$s = "Hello, ";<br />
$s2 = $s . "World!";</td>
<td>s = "Hello, "<br />
s2 = s + "World!"<br />
<br />
<span style="color: gray"># juxtaposition can be used to<br />
# concatenate literals:</span><br />
s2 = "Hello, " 'World!'</td>
</tr>
<tr>
<td><a name="str-replicate" id="str-replicate"></a><a href="scripting#str-replicate-note">replicate</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>let hbar = _.repeat('-', 80);</td>
<td>hbar = '-' * 80</td>
<td>$hbar = str_repeat("-", 80);</td>
<td>hbar = "-" * 80</td>
</tr>
<tr>
<td><a name="translate-case" id="translate-case"></a><a href="scripting#translate-case-note">translate case</a><br />
<span style="color: gray"><em>to upper, to lower</em></span></td>
<td>'lorem'.toUpperCase()<br />
'LOREM'.toLowerCase()</td>
<td>'lorem'.upper()<br />
'LOREM'.lower()</td>
<td>mb_strtoupper("lorem")<br />
mb_strtolower("LOREM")<br />
<span style="color: gray"># strtoupper/strtolower are ASCII only</span></td>
<td>"lorem".upcase<br />
"LOREM".downcase</td>
</tr>
<tr>
<td><a name="capitalize" id="capitalize"></a><a href="scripting#capitalize-note">capitalize</a><br />
<span style="color: gray"><em>string, words</em></span></td>
<td>_.capitalize('lorem');<br />
<span style="color: gray"><em>none</em></span></td>
<td>import string<br />
<br />
'lorem'.capitalize()<br />
string.capwords('lorem ipsum')</td>
<td><span style="color: gray"># ASCII only:</span><br />
ucfirst(strtolower("lorem"))<br />
ucwords(strtolower("lorem ipsum"))<br />
<span style="color: gray"># Unicode title case:</span><br />
mb_convert_case("lorem ipsum", MB_CASE_TITLE)</td>
<td>"lorem".capitalize<br />
<span style="color: gray"><em>none</em></span></td>
</tr>
<tr>
<td><a name="trim" id="trim"></a><a href="scripting#trim-note">trim</a><br />
<span style="color: gray"><em>both sides, left, right</em></span></td>
<td>' lorem '.trim()<br />
' lorem'.trimLeft()<br />
'lorem '.trimRight()</td>
<td>' lorem '.strip()<br />
' lorem'.lstrip()<br />
'lorem '.rstrip()</td>
<td>trim(" lorem ")<br />
ltrim(" lorem")<br />
rtrim("lorem ")</td>
<td>" lorem ".strip<br />
" lorem".lstrip<br />
"lorem ".rstrip</td>
</tr>
<tr>
<td><a name="pad" id="pad"></a><a href="scripting#pad-note">pad</a><br />
<span style="color: gray"><em>on right, on left, centered</em></span></td>
<td>_.padStart('lorem', 10)<br />
_.padEnd('lorem', 10)<br />
_.pad('lorem', 10)</td>
<td>'lorem'.ljust(10)<br />
'lorem'.rjust(10)<br />
'lorem'.center(10)</td>
<td>$s = "lorem";<br />
$delta = strlen($s) - mb_strlen($s);<br />
str_pad($s, 10 + $delta)<br />
str_pad("$s, 10 + $delta, " ", STR_PAD_LEFT)<br />
str_pad($s, 10 + $delta, " ", STR_PAD_BOTH)</td>
<td>"lorem".ljust(10)<br />
"lorem".rjust(10)<br />
"lorem".center(10)</td>
</tr>
<tr>
<td><a name="num-to-str" id="num-to-str"></a><a href="scripting#num-to-str-note">number to string</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>'value: ' + 8</td>
<td>'value: ' + str(8)</td>
<td>"value: " . 8</td>
<td>"value: " + 8.to_s</td>
</tr>
<tr>
<td><a name="fmt-float" id="fmt-float"></a><a href="scripting#fmt-float-note">format float</a></td>
<td>'' + Math.round(Math.PI * 100) / 100</td>
<td>import math<br />
<br />
'%.2f' % math.pi<br />
'{:.3}'.format(math.pi)<br />
<span style="color: gray"># Python 3.6:</span><br />
f'{math.pi:.{3}}'</td>
<td>number_format(M_PI, 2)</td>
<td>include Math<br />
<br />
'%.2f' % PI<br />
"#{PI.round(2)}"</td>
</tr>
<tr>
<td><a name="str-to-num" id="str-to-num"></a><a href="scripting#str-to-num-note">string to number</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>7 + parseInt('12;, 10)<br />
73.9 + parseFloat('.037')<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> 12:</span><br />
parseInt('12A')<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> NaN:</span><br />
parseInt('A')</td>
<td>7 + int('12')<br />
73.9 + float('.037')<br />
<br />
<span style="color: gray"># raises ValueError:</span><br />
int('12A')<br />
<span style="color: gray"># raises ValueError:</span><br />
int('A')</td>
<td>7 + "12"<br />
73.9 + ".037"<br />
<br />
<span style="color: gray"># 12:</span><br />
0 + "12A"<br />
<span style="color: gray"># 0:</span><br />
0 + "A"</td>
<td>7 + "12".to_i<br />
73.9 + ".037".to_f<br />
<br />
<span style="color: gray"># 12:</span><br />
"12A".to_i<br />
<span style="color: gray"># 0:</span><br />
"A".to_i</td>
</tr>
<tr>
<td><a name="str-join" id="str-join"></a><a href="scripting#str-join-note">string join</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>['do', 're', 'mi'].join(' ')</td>
<td>' '.join(['do', 're', 'mi', 'fa'])<br />
<br />
<span style="color: gray"># raises TypeError:</span><br />
' '.join([1, 2, 3])</td>
<td>$a = ["do", "re", "mi", "fa"];<br />
implode(" ", $a)</td>
<td>%w(do re mi fa).join(' ')<br />
<br />
<span style="color: gray"># implicitly converted to strings:</span><br />
[1, 2, 3].join(' ')</td>
</tr>
<tr>
<td><a name="split" id="split"></a><a href="scripting#split-note">split</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> [ 'do', 're', '', 'mi', '' ]:</span><br />
'do re<span style="white-space: pre-wrap;">  </span>mi '.split(' ')<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> [ 'do', 're', 'mi', '' ]:</span><br />
'do re<span style="white-space: pre-wrap;">  </span>mi '.split(/\s+/)</td>
<td><span style="color: gray"># ['do', 're', '', 'mi', '']:</span><br />
'do re<span style="white-space: pre-wrap;">  </span>mi '.split(' ')<br />
<br />
<span style="color: gray"># ['do', 're', 'mi']:</span><br />
'do re<span style="white-space: pre-wrap;">  </span>mi '.split()</td>
<td><span style="color: gray"># [ "do", "re", "", "mi", "" ]:</span><br />
explode(" ", "do re<span style="white-space: pre-wrap;">  </span>mi ")<br />
<br />
<span style="color: gray"># [ "do", "re", "mi", "" ]:</span><br />
preg_split('/\s+/', "do re<span style="white-space: pre-wrap;">  </span>mi ")</td>
<td><span style="color: gray"># ["do", "re", "", "mi"]:</span><br />
"do re<span style="white-space: pre-wrap;">  </span>mi ".split(/ /)<br />
<br />
<span style="color: gray"># ["do", "re", "mi"]:</span><br />
"do re<span style="white-space: pre-wrap;">  </span>mi ".split</td>
</tr>
<tr>
<td><a name="split-in-two" id="split-in-two"></a><a href="scripting#split-in-two-note">split in two</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>'do re mi fa'.split(/\s+/, 2)</td>
<td>'do re mi fa'.split(None, 1)</td>
<td>preg_split('/\s+/', "do re mi fa", 2)</td>
<td>"do re mi fa".split(/\s+/, 2)</td>
</tr>
<tr>
<td><a name="split-keep-delimiters" id="split-keep-delimiters"></a><a href="scripting#split-keep-delimiters-note">split and keep delimiters</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>re.split('(\s+)', 'do re mi fa')</td>
<td>preg_split('/(\s+)/', "do re mi fa",<br />
<span style="white-space: pre-wrap;">  </span>NULL, PREG_SPLIT_DELIM_CAPTURE)</td>
<td>"do re mi fa".split(/(\s+)/)</td>
</tr>
<tr>
<td><a name="prefix-suffix-test" id="prefix-suffix-test"></a><a href="scripting#prefix-suffix-test-note">prefix and suffix test</a></td>
<td>'foobar'.startsWith('foo')<br />
'foobar'.endsWith('bar')</td>
<td>'foobar'.startswith('foo')<br />
'foobar'.endswith('bar')</td>
<td></td>
<td>'foobar'.start_with?('foo')<br />
'foobar'.end_with?('bar')</td>
</tr>
<tr>
<td><a name="str-len" id="str-len"></a><a href="scripting#str-len-note">length</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>'lorem'.length</td>
<td>len('lorem')</td>
<td>mb_strlen("lorem")<br />
<span style="color: gray"># strlen() counts bytes</span></td>
<td>"lorem".length<br />
"lorem".size</td>
</tr>
<tr>
<td><a name="index-substr" id="index-substr"></a><a href="scripting#index-substr-note">index of substring</a><br />
<span style="color: gray"><em>first, last</em></span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> returns -1 if not found:</span><br />
'lorem ipsum'.indexOf('ipsum')</td>
<td><span style="color: gray"># raises ValueError if not found:</span><br />
'do re re'.index('re')<br />
'do re re'.rindex('re')<br />
<br />
<span style="color: gray"># returns -1 if not found:</span><br />
'do re re'.find('re')<br />
'do re re'.rfind('re')</td>
<td><span style="color: gray"># returns FALSE if not found:</span><br />
mb_strpos("do re re", "re")<br />
mb_strrpos("do re re", "re")</td>
<td><span style="color: gray"># returns nil if not found:</span><br />
"do re re".index("re")<br />
"do re re".rindex("re")</td>
</tr>
<tr>
<td><a name="extract-substr" id="extract-substr"></a><a href="scripting#extract-substr-note">extract substring</a><br />
<span style="color: gray"><em>by start and length, by start and end, by successive starts</em></span></td>
<td>'lorem ipsum'.substr(6, 5)<br />
'lorem ipsum'.substring(6, 11)</td>
<td><span style="color: gray"><em>none</em></span><br />
<span style="color: gray"><em>none</em></span><br />
'lorem ipsum'[6:11]</td>
<td>mb_substr("lorem ipsum", 6, 5)<br />
<span style="color: gray"><em>none</em></span><br />
<span style="color: gray"><em>none</em></span></td>
<td>"lorem ipsum"[6, 5]<br />
"lorem ipsum"[6<span style="white-space: pre-wrap;">..</span>10]<br />
"lorem ipsum"[6<span style="white-space: pre-wrap;">...</span>11]</td>
</tr>
<tr>
<td><a name="bytes-type" id="bytes-type"></a><a href="scripting#bytes-type-note">byte array type</a></td>
<td>Buffer</td>
<td>bytes<br />
<br />
<span style="color: gray"># In Python 2, str also byte array type</span></td>
<td>string</td>
<td>Array <span style="color: gray"><em>of</em></span> Fixnum</td>
</tr>
<tr>
<td><a name="bytes-to-str" id="bytes-to-str"></a><a href="scripting#bytes-to-str-note">byte array to string</a></td>
<td>let a = Buffer.from([0xce, 0xbb]);<br />
let s = a.toString('utf-8');</td>
<td>s = b'\xce\xbb'.decode('utf-8')</td>
<td><span style="color: gray"><em>strings are byte arrays</em></span></td>
<td>a = "\u03bb".bytes<br />
s = a.pack("C*").force_encoding('utf-8')</td>
</tr>
<tr>
<td><a name="str-to-bytes" id="str-to-bytes"></a><a href="scripting#str-to-bytes-note">string to byte array</a></td>
<td>a = Buffer.from('\u03bb')</td>
<td>a = '\u03bb'.encode('utf-8')<br />
<br />
<span style="color: gray"># Python 2:</span><br />
a = u'\u03bb'.encode('utf-8')</td>
<td><span style="color: gray"><em>strings are byte arrays</em></span></td>
<td>a = "\u03bb".bytes</td>
</tr>
<tr>
<td><a name="lookup-char" id="lookup-char"></a><a href="scripting#lookup-char-note">character lookup</a></td>
<td>'lorem ipsum'[6]</td>
<td>'lorem ipsum'[6]</td>
<td>mb_substr("lorem ipsum", 6, 1)<br />
<span style="color: gray"># byte lookup:</span><br />
"lorem ipsum"[6]</td>
<td>"lorem ipsum"[6]</td>
</tr>
<tr>
<td><a name="chr-ord" id="chr-ord"></a><a href="scripting#chr-ord-note">chr and ord</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>String.fromCharCode(65)<br />
'A'.charCodeAt(0)</td>
<td>chr(65)<br />
ord('A')</td>
<td><span style="color: gray"># ASCII only:</span><br />
chr(65)<br />
ord("A")</td>
<td>65.chr('UTF-8')<br />
"A".ord</td>
</tr>
<tr>
<td><a name="str-to-char-array" id="str-to-char-array"></a><a href="scripting#str-to-char-array-note">to array of characters</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>'abcd'.split('')</td>
<td>list('abcd')</td>
<td>str_split("abcd")</td>
<td>"abcd".split("")</td>
</tr>
<tr>
<td><a name="translate-char" id="translate-char"></a><a href="scripting#translate-char-note">translate characters</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>from string import ascii_lowercase<br />
<br />
ins = ascii_lowercase<br />
outs = ins[13:] + ins[:13]<br />
table = str.maketrans(ins, outs)<br />
'hello'.translate(table)</td>
<td>$ins = implode(range("a", "z"));<br />
$outs = substr($ins, 13, 13) .<br />
<span style="white-space: pre-wrap;">  </span>substr($ins, 0, 13);<br />
strtr("hello", $ins, $outs)</td>
<td>"hello".tr("a-z", "n-za-m")</td>
</tr>
<tr>
<td><a name="delete-char" id="delete-char"></a><a href="scripting#delete-char-note">delete characters</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>table = {ord(ch): None for ch in "aeiou"}<br />
"disemvowel me".translate(table)</td>
<td>$vowels = str_split("aeiou");<br />
$s = "disemvowel me";<br />
$s = str_replace($vowels, "", $s);</td>
<td>"disemvowel me".delete("aeiou")</td>
</tr>
<tr>
<td><a name="squeeze-char" id="squeeze-char"></a><a href="scripting#squeeze-char-note">squeeze characters</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>re.sub('(\s)+', r'\1',<br />
<span style="white-space: pre-wrap;">  </span>'too<span style="white-space: pre-wrap;">   </span>much<span style="white-space: pre-wrap;">   </span>space')</td>
<td>$s = "too<span style="white-space: pre-wrap;">   </span>much<span style="white-space: pre-wrap;">   </span>space";<br />
$s = = preg_replace('/(\s)+/', '\1', $s);</td>
<td>"too<span style="white-space: pre-wrap;">   </span>much<span style="white-space: pre-wrap;">   </span>space".squeeze(" ")</td>
</tr>
<tr>
<th colspan="5"><a name="regexes" id="regexes"></a><a href="scripting#regexes-note">regular expressions</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="regex-literal" id="regex-literal"></a><a href="scripting#regex-literal-note">literal, custom delimited literal</a></td>
<td>/lorem|ipsum/</td>
<td>re.compile(r'lorem|ipsum')<br />
<span style="color: gray"><em>none</em></span></td>
<td>'/lorem|ipsum/'<br />
'(/etc/hosts)'</td>
<td>/lorem|ipsum/<br />
%r(/etc/hosts)<br />
<span style="color: gray"># double quoted string escapes<br />
# and #{} substitution can be used</span></td>
</tr>
<tr>
<td><a name="ascii-char-class-abbrev" id="ascii-char-class-abbrev"></a><a href="scripting#ascii-char-class-abbrev-note">ascii character class abbreviations</a></td>
<td>.<span style="white-space: pre-wrap;">   </span>[^\n]<br />
\d<span style="white-space: pre-wrap;">  </span>[0-9]<br />
\D<span style="white-space: pre-wrap;">  </span>[^0-9]<br />
\s<span style="white-space: pre-wrap;">  </span>[ \t\r\n\f]<br />
\S<span style="white-space: pre-wrap;">  </span>[^ \t\r\n\f]<br />
\w<span style="white-space: pre-wrap;">  </span>[A-Za-z0-9_]<br />
\W<span style="white-space: pre-wrap;">  </span>[^A-Za-z0-9_]</td>
<td>.<span style="white-space: pre-wrap;">   </span>[^\n]<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>with</em> re.S <em>modifier matches all chars</em></span><br />
\d<span style="white-space: pre-wrap;">  </span>[0-9]<br />
\D<span style="white-space: pre-wrap;">  </span>[^0-9]<br />
\s<span style="white-space: pre-wrap;">  </span>[ \t\r\n\f]<br />
\S<span style="white-space: pre-wrap;">  </span>[^ \t\r\n\f]<br />
\w<span style="white-space: pre-wrap;">  </span>[A-Za-z0-9_]<br />
\W<span style="white-space: pre-wrap;">  </span>[^A-Za-z0-9_]<br />
<br />
<span style="color: gray"><em>In Python 3, the above definitions are used when</em> re.A <em>is in effect.</em></span></td>
<td>.<span style="white-space: pre-wrap;">   </span>[^\n]<br />
\d<span style="white-space: pre-wrap;">  </span>[0-9]<br />
\D<span style="white-space: pre-wrap;">  </span>[^0-9]<br />
\h<span style="white-space: pre-wrap;">  </span>[ \t]<br />
\H<span style="white-space: pre-wrap;">  </span>[^ \t]<br />
\s<span style="white-space: pre-wrap;">  </span>[ \t\r\n\f]<br />
\S<span style="white-space: pre-wrap;">  </span>[^ \t\r\n\f]<br />
\w<span style="white-space: pre-wrap;">  </span>[A-Za-z0-9_]<br />
\W<span style="white-space: pre-wrap;">  </span>[^A-Za-z0-9_]</td>
<td>.<span style="white-space: pre-wrap;">   </span>[^\n]<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>with</em> m <em>modifier matches all chars</em></span><br />
\d<span style="white-space: pre-wrap;">  </span>[0-9]<br />
\D<span style="white-space: pre-wrap;">  </span>[^0-9]<br />
\h<span style="white-space: pre-wrap;">  </span>[0-9a-fA-F]<br />
\H<span style="white-space: pre-wrap;">  </span>[^0-9a-fA-F]<br />
\s<span style="white-space: pre-wrap;">  </span>[ \t\r\n\f]<br />
\S<span style="white-space: pre-wrap;">  </span>[^ \t\r\n\f]<br />
\w<span style="white-space: pre-wrap;">  </span>[A-Za-z0-9_]<br />
\W<span style="white-space: pre-wrap;">  </span>[^A-Za-z0-9_]</td>
</tr>
<tr>
<td><a name="unicode-char-class-abbrev" id="unicode-char-class-abbrev"></a><a href="scripting#unicode-char-class-abbrev-note">unicode character class abbreviations</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>.<span style="white-space: pre-wrap;">   </span>[^\n]<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>with</em> re.S <em>modifier matches all chars</em></span><br />
\d<span style="white-space: pre-wrap;">  </span>[<span style="color: gray"><em>Nd</em></span>]<span style="white-space: pre-wrap;">  </span><span style="color: gray">Nd: <em>Number, decimal digit</em></span><br />
\D<span style="white-space: pre-wrap;">  </span>[^<span style="color: gray"><em>Nd</em></span>]<br />
\s<span style="white-space: pre-wrap;">  </span>[<span style="color: gray"><em>Z</em></span>\t\n\r\f\v\x1c\x1d\x1e\x1f\x85]<br />
\S<span style="white-space: pre-wrap;">  </span>[^<span style="color: gray"><em>Z</em></span>\t\n\r\f\v\x1c\x1d\x1e\x1f\x85]<br />
\w [<span style="color: gray"><em>LN</em></span>_]<span style="white-space: pre-wrap;">  </span><span style="color: gray">L: <em>Letter</em>; N: <em>Number</em></span><br />
\W [<span style="color: gray">^<em>LN</em></span>_]<br />
<br />
<span style="color: gray"><em>In Python 2, the above definitions are used when</em> re.U <em>is in effect.</em></span></td>
<td><span style="color: gray"><em>POSIX character classes such as</em> [[:alpha:]] <em>are available, but they match sets of ASCII characters. General category values (e.g.</em> \p{L}, \p{Lu}<em>) can be used. Morever, they can be used inside character classes (.e.g.</em> [\p{L}\p{N}]<em>).</em></span></td>
<td>.<br />
\p{Digit}<br />
\p{^Digit}<br />
\p{Space}<br />
\p{^Space}<br />
\p{Word}<br />
\p{^Word}<br />
<br />
<span style="color: gray"><em>POSIX character classes (e.g.</em> <span style="white-space: pre-wrap;">[[:alpha:]]</span><em>), general category values (e.g.</em> \p{L}, \p{Lu}<em>), and script names (e.g.</em> \p{Greek}) <em>also supported.</em></span></td>
</tr>
<tr>
<td><a name="regex-anchors" id="regex-anchors"></a><a href="scripting#regex-anchors-note">anchors</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>^<span style="white-space: pre-wrap;">   </span><span style="color: gray"><em>start of string or line with</em> m <em>modifier</em></span><br />
$<span style="white-space: pre-wrap;">   </span><span style="color: gray"><em>end of string or line with</em> m <em>modifier</em></span><br />
\b<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>word boundary:</em> \w\W <em>or</em> \W\w</span><br />
\B<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>non word boundary</em></span></td>
<td>^<span style="white-space: pre-wrap;">   </span><span style="color: gray"><em>start of string or line with</em> re.M</span><br />
$<span style="white-space: pre-wrap;">   </span><span style="color: gray"><em>end of string or line with</em> re.M</span><br />
\A<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>start of string</em></span><br />
\b<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>word boundary:</em> \w\W <em>or</em> \W\w</span><br />
\B<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>non word boundary</em></span><br />
\Z<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>end of string</em></span></td>
<td>^<span style="white-space: pre-wrap;">   </span><span style="color: gray"><em>start of string or line with</em> m <em>modifier</em></span><br />
$<span style="white-space: pre-wrap;">   </span><span style="color: gray"><em>end of string or line with</em> m <em>modifier</em></span><br />
\A<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>start of string</em></span><br />
\b<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>word boundary:</em> \w\W <em>or</em> \W\w</span><br />
\B<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>non word boundary</em></span><br />
\z<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>end of string</em></span><br />
\Z<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>end of string, excluding final newline</em></span></td>
<td>^<span style="white-space: pre-wrap;">   </span><span style="color: gray"><em>start of line</em></span><br />
$<span style="white-space: pre-wrap;">   </span><span style="color: gray"><em>end of line</em></span><br />
\A<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>start of string</em></span><br />
\b<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>unicode-aware word boundary</em></span><br />
\B<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>unicode-aware non word boundary</em></span><br />
\z<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>end of string</em></span><br />
\Z<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>end of string, excluding final newline</em></span></td>
</tr>
<tr>
<td><a name="regex-test" id="regex-test"></a><a href="scripting#regex-test-note">match test</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>if (s.match(/1999/)) {<br />
<span style="white-space: pre-wrap;">  </span>console.log('party!');<br />
}</td>
<td>if re.search('1999', s):<br />
<span style="white-space: pre-wrap;">  </span>print('party!')</td>
<td>if (preg_match('/1999/', $s)) {<br />
<span style="white-space: pre-wrap;">  </span>echo "party!\n";<br />
}</td>
<td>if /1999/.match(s)<br />
<span style="white-space: pre-wrap;">  </span>puts "party!"<br />
end</td>
</tr>
<tr>
<td><a name="case-insensitive-regex" id="case-insensitive-regex"></a><a href="scripting#case-insensitive-regex-note">case insensitive match test</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>'Lorem'.match(/lorem/i)</td>
<td>re.search('lorem', 'Lorem', re.I)</td>
<td>preg_match('/lorem/i', "Lorem")</td>
<td>/lorem/i.match("Lorem")</td>
</tr>
<tr>
<td><a name="regex-modifiers" id="regex-modifiers"></a><a href="scripting#regex-modifiers-note">modifiers</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>g<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>used for global substitution and scanning</em></span><br />
i<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>make case insensitive</em></span><br />
m<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>change meaning of</em> ^ <em>and</em> $</span><br />
u<span style="white-space: pre-wrap;">  </span><span style="color: gray">\u{} <em>syntax and astral character support</em></span><br />
y<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>used to scan in loop</em></span></td>
<td>re.A<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>change meaning of</em> \b \B \d \D \s \S \w \W</span><br />
re.I<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>make case insensitive</em></span><br />
re.M<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>change meaning of</em> ^ <em>and</em> $</span><br />
re.S<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>change meaning of</em> .</span><br />
re.X<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>ignore whitespace outside char class</em></span></td>
<td>i<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>make case insensitive</em></span><br />
m<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>change meaning of</em> ^ <em>and</em> $</span><br />
s<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>change meaning of</em> .</span><br />
x<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>ignore whitespace outside char class</em></span></td>
<td>i<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>make case insensitive</em></span><br />
o<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>interpolate #{} in literal once</em></span><br />
m<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>change meaning of</em> .</span><br />
x<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>ignore whitespace outside char class</em></span></td>
</tr>
<tr>
<td><a name="subst" id="subst"></a><a href="scripting#subst-note">substitution</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>s = 'do re mi mi mi';<br />
s.replace(/mi/g, 'ma');</td>
<td>s = 'do re mi mi mi'<br />
s = re.compile('mi').sub('ma', s)</td>
<td>$s = "do re mi mi mi";<br />
$s = preg_replace('/mi/', "ma", $s);</td>
<td>s = "do re mi mi mi"<br />
s.gsub!(/mi/, "ma")</td>
</tr>
<tr>
<td><a name="match-prematch-postmatch" id="match-prematch-postmatch"></a><a href="scripting#match-prematch-postmatch-note">match, prematch, postmatch</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>m = /\d{4}/.exec(s);<br />
if (m) {<br />
<span style="white-space: pre-wrap;">  </span>match = m[0];<br />
<span style="white-space: pre-wrap;">  </span><span style="color: gray"><span style="white-space: pre-wrap;">//</span> no prematch or postmatch</span><br />
}</td>
<td>m = re.search('\d{4}', s)<br />
if m:<br />
<span style="white-space: pre-wrap;">  </span>match = m.group()<br />
<span style="white-space: pre-wrap;">  </span>prematch = s[0:m.start(0)]<br />
<span style="white-space: pre-wrap;">  </span>postmatch = s[m.end(0):len(s)]</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>m = /\d{4}/.match(s)<br />
if m<br />
<span style="white-space: pre-wrap;">  </span>match = m[0]<br />
<span style="white-space: pre-wrap;">  </span>prematch = m.pre_match<br />
<span style="white-space: pre-wrap;">  </span>postmatch = m.post_match<br />
end</td>
</tr>
<tr>
<td><a name="group-capture" id="group-capture"></a><a href="scripting#group-capture-note">group capture</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>rx = /^(\d{4})-(\d{2})-(\d{2})$/;<br />
m = rx.exec('2009-06-03');<br />
yr = m[1];<br />
mo = m[2];<br />
dy = m[3];</td>
<td>rx = '(\d{4})-(\d{2})-(\d{2})'<br />
m = re.search(rx, '2010-06-03')<br />
yr, mo, dy = m.groups()</td>
<td>$s = "2010-06-03";<br />
$rx = '/(\d{4})-(\d{2})-(\d{2})/';<br />
preg_match($rx, $s, $m);<br />
list($_, $yr, $mo, $dy) = $m;</td>
<td>rx = /(\d{4})-(\d{2})-(\d{2})/<br />
m = rx.match("2010-06-03")<br />
yr, mo, dy = m[1..3]</td>
</tr>
<tr>
<td><a name="named-group-capture" id="named-group-capture"></a><a href="scripting#named-group-capture-note">named group capture</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>rx = '^(?P&lt;file&gt;.+)\.(?P&lt;suffix&gt;.+)$'<br />
m = re.search(rx, 'foo.txt')<br />
<br />
m.groupdict()['file']<br />
m.groupdict()['suffix']</td>
<td>$s = "foo.txt";<br />
$rx = '/^(?P&lt;file&gt;.+)\.(?P&lt;suffix&gt;.+)$/';<br />
preg_match($rx, $s, $m);<br />
<br />
$m["file"]<br />
$m["suffix"]</td>
<td>rx = /^(?&lt;file&gt;.+)\.(?&lt;suffix&gt;.+)$/<br />
m = rx.match('foo.txt')<br />
<br />
m["file"]<br />
m["suffix"]</td>
</tr>
<tr>
<td><a name="scan" id="scan"></a><a href="scripting#scan-note">scan</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>let a = 'dolor sit amet'.match(/\w+/g);</td>
<td>s = 'dolor sit amet'<br />
a = re.findall('\w+', s)</td>
<td>$s = "dolor sit amet";<br />
preg_match_all('/\w+/', $s, $m);<br />
$a = $m[0];</td>
<td>a = "dolor sit amet".scan(/\w+/)</td>
</tr>
<tr>
<td><a name="backreference" id="backreference"></a><a href="scripting#backreference-note">backreference in match and substitution</a></td>
<td>/(\w+) \1/.exec('do do')<br />
<br />
'do re'.replace(/(\w+) (\w+)/, '$2 $1')</td>
<td><span style="color: gray"><em>none</em></span><br />
<br />
rx = re.compile('(\w+) (\w+)')<br />
rx.sub(r'\2 \1', 'do re')</td>
<td>preg_match('/(\w+) \1/', "do do")<br />
<br />
$s = "do re";<br />
$rx = '/(\w+) (\w+)/';<br />
$s = preg_replace($rx, '\2 \1', $s);</td>
<td>/(\w+) \1/.match("do do")<br />
<br />
"do re".sub(/(\w+) (\w+)/, '\2 \1')</td>
</tr>
<tr>
<td><a name="recursive-regex" id="recursive-regex"></a><a href="scripting#recursive-regex-note">recursive regex</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>'/\(([^()]*|($R))\)/'</td>
<td>/(?&lt;foo&gt;\(([^()]*|\g&lt;foo&gt;)*\))/</td>
</tr>
<tr>
<th colspan="5"><a name="dates-time" id="dates-time"></a><a href="scripting#dates-time-note">dates and time</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="broken-down-datetime-type" id="broken-down-datetime-type"></a><a href="scripting#broken-down-datetime-type-note">broken-down datetime type</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>Date</td>
<td>datetime.datetime</td>
<td>DateTime</td>
<td>Time</td>
</tr>
<tr>
<td><a name="current-datetime" id="current-datetime"></a><a href="scripting#current-datetime-note">current datetime</a></td>
<td>let t = new Date();</td>
<td>import datetime<br />
<br />
t = datetime.datetime.now()<br />
utc = datetime.datetime.utcnow()</td>
<td>$t = new DateTime("now");<br />
$utc_tmz = new DateTimeZone("UTC");<br />
$utc = new DateTime("now", $utc_tmz);</td>
<td>t = Time.now<br />
utc = Time.now.utc</td>
</tr>
<tr>
<td><a name="current-unix-epoch" id="current-unix-epoch"></a><a href="scripting#current-unix-epoch-note">current unix epoch</a></td>
<td>(new Date()).getTime() / 1000</td>
<td>import datetime<br />
<br />
t = datetime.datetime.now()<br />
epoch = int(t.strftime("%s"))</td>
<td>$epoch = time();</td>
<td>epoch = Time.now.to_i</td>
</tr>
<tr>
<td><a name="broken-down-datetime-to-unix-epoch" id="broken-down-datetime-to-unix-epoch"></a><a href="scripting#broken-down-datetime-to-unix-epoch-note">broken-down datetime to unix epoch</a></td>
<td>Math.round(t.getTime() / 1000)</td>
<td>from datetime import datetime as dt<br />
<br />
epoch = int(t.strftime("%s"))</td>
<td>$epoch = $t-&gt;getTimestamp();</td>
<td>epoch = t.to_i</td>
</tr>
<tr>
<td><a name="unix-epoch-to-broken-down-datetime" id="unix-epoch-to-broken-down-datetime"></a><a href="scripting#unix-epoch-to-broken-down-datetime-note">unix epoch to broken-down datetime</a></td>
<td>let epoch = 1315716177;<br />
let t2 = new Date(epoch * 1000);</td>
<td>t = dt.fromtimestamp(1304442000)</td>
<td>$t2 = new DateTime();<br />
$t2-&gt;setTimestamp(1304442000);</td>
<td>t = Time.at(1304442000)</td>
</tr>
<tr>
<td><a name="fmt-datetime" id="fmt-datetime"></a><a href="scripting#fmt-datetime-note">format datetime</a></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> npm install moment</span><br />
let moment = require('moment');<br />
<br />
let t = moment(new Date());<br />
let fmt = 'YYYY-MM-DD HH:mm:ss';<br />
console.log(t.format(fmt));</td>
<td>t.strftime('%Y-%m-%d %H:%M:%S')</td>
<td>strftime("%Y-%m-%d %H:%M:%S", $epoch);<br />
date("Y-m-d H:i:s", $epoch);<br />
$t-&gt;format("Y-m-d H:i:s");</td>
<td>t.strftime("%Y-%m-%d %H:%M:%S")</td>
</tr>
<tr>
<td><a name="parse-datetime" id="parse-datetime"></a><a href="scripting#parse-datetime-note">parse datetime</a></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> npm install moment</span><br />
let moment = require('moment');<br />
<br />
let fmt = 'YYYY-MM-DD HH:mm:ss';<br />
let s = '2011-05-03 10:00:00';<br />
let t = moment(s, fmt);</td>
<td>from datetime import datetime<br />
<br />
s = '2011-05-03 10:00:00'<br />
fmt = '%Y-%m-%d %H:%M:%S'<br />
t = datetime.strptime(s, fmt)</td>
<td>$fmt = "Y-m-d H:i:s";<br />
$s = "2011-05-03 10:00:00";<br />
$t = DateTime::createFromFormat($fmt,<br />
<span style="white-space: pre-wrap;">  </span>$s);</td>
<td>require 'date'<br />
<br />
s = "2011-05-03 10:00:00"<br />
fmt = "%Y-%m-%d %H:%M:%S"<br />
t = DateTime.strptime(s, fmt).to_time</td>
</tr>
<tr>
<td><a name="parse-datetime-without-fmt" id="parse-datetime-without-fmt"></a><a href="scripting#parse-datetime-without-fmt-note">parse datetime w/o format</a></td>
<td>let t = new Date('July 7, 1999');</td>
<td><span style="color: gray"># pip install python-dateutil</span><br />
import dateutil.parser<br />
<br />
s = 'July 7, 1999'<br />
t = dateutil.parser.parse(s)</td>
<td>$epoch = strtotime("July 7, 1999");</td>
<td>require 'date'<br />
<br />
s = "July 7, 1999"<br />
t = Date.parse(s).to_time</td>
</tr>
<tr>
<td><a name="date-parts" id="date-parts"></a><a href="scripting#date-parts-note">date parts</a></td>
<td>t.getFullYear()<br />
t.getMonth() + 1<br />
t.getDate() <span style="color: gray"><span style="white-space: pre-wrap;">//</span> getDay() is day of week</span></td>
<td>t.year<br />
t.month<br />
t.day</td>
<td>(int)$t-&gt;format("Y")<br />
(int)$t-&gt;format("m")<br />
(int)$t-&gt;format("d")</td>
<td>t.year<br />
t.month<br />
t.day</td>
</tr>
<tr>
<td><a name="time-parts" id="time-parts"></a><a href="scripting#time-parts-note">time parts</a></td>
<td>t.getHours()<br />
t.getMinutes()<br />
t.getSeconds()</td>
<td>t.hour<br />
t.minute<br />
t.second</td>
<td>(int)$t-&gt;format("H")<br />
(int)$t-&gt;format("i")<br />
(int)$t-&gt;format("s")</td>
<td>t.hour<br />
t.min<br />
t.sec</td>
</tr>
<tr>
<td><a name="build-datetime" id="build-datetime"></a><a href="scripting#build-datetime-note">build broken-down datetime</a></td>
<td>let yr = 1999;<br />
let mo = 9;<br />
let dy = 10;<br />
let hr = 23;<br />
let mi = 30;<br />
let ss = 0;<br />
let t = new Date(yr, mo - 1, dy,<br />
<span style="white-space: pre-wrap;">  </span>hr, mi, ss);</td>
<td>import datetime<br />
<br />
yr = 1999<br />
mo = 9<br />
dy = 10<br />
hr = 23<br />
mi = 30<br />
ss = 0<br />
t = datetime.datetime(yr, mo, dy, hr, mi, ss)</td>
<td></td>
<td>yr = 1999<br />
mo = 9<br />
dy = 10<br />
hr = 23<br />
mi = 30<br />
ss = 0<br />
t = Time.new(yr, mo, dy, hr, mi, ss)</td>
</tr>
<tr>
<td><a name="datetime-subtraction" id="datetime-subtraction"></a><a href="scripting#datetime-subtraction-note">datetime subtraction</a></td>
<td><span style="color: gray">number <em>containing time difference in milliseconds</em></span></td>
<td><span style="color: gray">datetime.timedelta <em>object</em></span><br />
<br />
<span style="color: gray"><em>use</em> total_seconds() <em>method to convert to float representing difference in seconds</em></span></td>
<td><span style="color: gray"># DateInterval object if diff method used:</span><br />
$fmt = "Y-m-d H:i:s";<br />
$s = "2011-05-03 10:00:00";<br />
$then = DateTime::createFromFormat($fmt, $s);<br />
$now = new DateTime("now");<br />
$interval = $now-&gt;diff($then);</td>
<td><span style="color: gray">Float <em>containing time difference in seconds</em></span></td>
</tr>
<tr>
<td><a name="add-duration" id="add-duration"></a><a href="scripting#add-duration-note">add duration</a></td>
<td>let t1 = new Date();<br />
let delta = (10 * 60 + 3) * 1000;<br />
let t2 = new Date(t1.getTime() + delta);</td>
<td>import datetime<br />
<br />
delta = datetime.timedelta(<br />
<span style="white-space: pre-wrap;">  </span>minutes=10,<br />
<span style="white-space: pre-wrap;">  </span>seconds=3)<br />
t = datetime.datetime.now() + delta</td>
<td>$now = new DateTime("now");<br />
$now-&gt;add(new DateInterval("PT10M3S");</td>
<td>require 'date/delta'<br />
<br />
s = "10 min, 3 s"<br />
delta = Date::Delta.parse(s).in_secs<br />
t = Time.now + delta</td>
</tr>
<tr>
<td><a name="local-tmz-determination" id="local-tmz-determination"></a><a href="scripting#local-tmz-determination-note">local time zone determination</a></td>
<td><span style="color: gray">TZ environment variable or host time zone</span></td>
<td><span style="color: gray"><em>a</em> datetime <em>object has no time zone information unless a</em> tzinfo <em>object is provided when it is created</em></span></td>
<td><span style="color: gray"># DateTime objects can be instantiated<br />
# without specifying the time zone<br />
# if a default is set:</span><br />
$s = "America/Los_Angeles";<br />
date_default_timezone_set($s);</td>
<td><span style="color: gray"><em>if no time zone is specified the local time zone is used</em></span></td>
</tr>
<tr>
<td><a name="nonlocal-tmz" id="nonlocal-tmz"></a><a href="scripting#nonlocal-tmz-note">nonlocal time zone</a></td>
<td></td>
<td><span style="color: gray"># pip install pytz</span><br />
import pytz<br />
import datetime<br />
<br />
tmz = pytz.timezone('Asia/Tokyo')<br />
utc = datetime.datetime.utcnow()<br />
utc_dt = datetime.datetime(<br />
<span style="white-space: pre-wrap;">  </span>*utc.timetuple()[0:6],<br />
<span style="white-space: pre-wrap;">  </span>tzinfo=pytz.utc)<br />
jp_dt = utc_dt.astimezone(tmz)</td>
<td></td>
<td><span style="color: gray"># gem install tzinfo</span><br />
require 'tzinfo'<br />
<br />
tmz = TZInfo::Timezone.get("Asia/Tokyo")<br />
jp_time = tmz.utc_to_local(Time.now.utc)</td>
</tr>
<tr>
<td><a name="tmz-info" id="tmz-info"></a><a href="scripting#tmz-info-note">time zone info</a><br />
<br />
<span style="color: gray"><em>name and UTC offset</em></span></td>
<td></td>
<td>import time<br />
<br />
tm = time.localtime()<br />
<span style="white-space: pre-wrap;">  </span><br />
time.tzname[tm.tm_isdst]<br />
(time.timezone / -3600) + tm.tm_isdst</td>
<td>$tmz = date_timezone_get($t);<br />
<br />
timezone_name_get($tmz);<br />
date_offset_get($t) / 3600;</td>
<td>t.zone<br />
t.utc_offset / 3600</td>
</tr>
<tr>
<td><a name="daylight-savings-test" id="daylight-savings-test"></a><a href="scripting#daylight-savings-test-note">daylight savings test</a></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> npm install moment</span><br />
let moment = require('moment');<br />
<br />
moment(new Date()).isDST()</td>
<td>import time<br />
<br />
tm = time.localtime()<br />
<span style="white-space: pre-wrap;">  </span><br />
tm.tm_isdst</td>
<td>$t-&gt;format("I");</td>
<td>t.dst?</td>
</tr>
<tr>
<td><a name="microseconds" id="microseconds"></a><a href="scripting#microseconds-note">microseconds</a></td>
<td>t.getMilliseconds() * 1000<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> [sec, nanosec] since system boot:</span><br />
process.hrtime()</td>
<td>t.microsecond</td>
<td>list($frac, $sec) = explode(" ", microtime());<br />
$usec = $frac * 1000 * 1000;</td>
<td>t.usec</td>
</tr>
<tr>
<th colspan="5"><a name="arrays" id="arrays"></a><a href="scripting#arrays-note">arrays</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="array-literal" id="array-literal"></a><a href="scripting#array-literal-note">literal</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>a = [1, 2, 3, 4]</td>
<td>a = [1, 2, 3, 4]</td>
<td>$a = [1, 2, 3, 4];<br />
<br />
<span style="color: gray"># older syntax:</span><br />
$a = array(1, 2, 3, 4);</td>
<td>a = [1, 2, 3, 4]<br />
<br />
<span style="color: gray"># a = ['do', 're', 'mi']</span><br />
a = %w(do re mi)</td>
</tr>
<tr>
<td><a name="array-size" id="array-size"></a><a href="scripting#array-size-note">size</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>a.length</td>
<td>len(a)</td>
<td>count($a)</td>
<td>a.size<br />
a.length</td>
</tr>
<tr>
<td><a name="array-empty" id="array-empty"></a><a href="scripting#array-empty-note">empty test</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> TypeError if a is null or undefined:</span><br />
a.length === 0</td>
<td><span style="color: gray"># None tests as empty:</span><br />
not a</td>
<td><span style="color: gray"># NULL tests as empty:</span><br />
!$a</td>
<td><span style="color: gray"># NoMethodError if a is nil:</span><br />
a.empty?</td>
</tr>
<tr>
<td><a name="array-lookup" id="array-lookup"></a><a href="scripting#array-lookup-note">lookup</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>a[0]</td>
<td>a[0]<br />
<br />
<span style="color: gray"># returns last element:</span><br />
a[-1]</td>
<td>$a[0]<br />
<br />
<span style="color: gray"># PHP uses the same type for arrays and<br />
# dictionaries; indices can be negative<br />
# integers or strings</span></td>
<td>a[0]<br />
<br />
<span style="color: gray"># returns last element:</span><br />
a[-1]</td>
</tr>
<tr>
<td><a name="array-update" id="array-update"></a><a href="scripting#array-update-note">update</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>a[0] = 'lorem'</td>
<td>a[0] = 'lorem'</td>
<td>$a[0] = "lorem";</td>
<td>a[0] = "lorem"</td>
</tr>
<tr>
<td><a name="array-out-of-bounds" id="array-out-of-bounds"></a><a href="scripting#array-out-of-bounds-note">out-of-bounds behavior</a></td>
<td><span style="color: gray"><em>returns</em> undefined</span></td>
<td>a = []<br />
<span style="color: gray"># raises IndexError:</span><br />
a[10]<br />
<span style="color: gray"># raises IndexError:</span><br />
a[10] = 'lorem'</td>
<td>$a = [];<br />
<span style="color: gray"># evaluates as NULL:</span><br />
$a[10];<br />
<span style="color: gray"># increases array size to one:</span><br />
$a[10] = "lorem";</td>
<td>a = []<br />
<span style="color: gray"># evaluates as nil:</span><br />
a[10]<br />
<span style="color: gray"># increases array size to 11:</span><br />
a[10] = "lorem"</td>
</tr>
<tr>
<td><a name="array-element-index" id="array-element-index"></a><a href="scripting#array-element-index-note">element index</a><br />
<br />
<span style="color: gray"><em>first and last occurrence</em></span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> return -1 if not found:</span><br />
[6, 7, 7, 8].indexOf(7)<br />
[6, 7, 7, 8].lastIndexOf(7)</td>
<td>a = ['x', 'y', 'y', 'z']<br />
<br />
<span style="color: gray"># raises ValueError if not found:</span><br />
a.index('y')<br />
<span style="color: gray"><em>none</em></span></td>
<td>$a = ["x", "y", "y", "z"];<br />
<br />
<span style="color: gray"># returns FALSE if not found:</span><br />
$i = array_search("y", $a, TRUE);<br />
<span style="color: gray"><em>none</em></span></td>
<td>a = %w(x y y z)<br />
<br />
<span style="color: gray"># return nil if not found:</span><br />
a.index('y')<br />
a.rindex('y')</td>
</tr>
<tr>
<td><a name="array-slice" id="array-slice"></a><a href="scripting#array-slice-note">slice</a><br />
<span style="color: gray"><em>by endpoints, by length</em></span><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> select 3rd and 4th elements:</span><br />
['a', 'b', 'c', 'd'].slice(2, 4)<br />
<span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"># select 3rd and 4th elements:</span><br />
a[2:4]<br />
a[<span style="white-space: pre-wrap;">2:2</span> + 2]</td>
<td><span style="color: gray"># select 3rd and 4th elements:</span><br />
<span style="color: gray"><em>none</em></span><br />
array_slice($a, 2, 2)</td>
<td><span style="color: gray"># select 3rd and 4th elements:</span><br />
a[2..3]<br />
a[2, 2]</td>
</tr>
<tr>
<td><a name="array-slice-to-end" id="array-slice-to-end"></a><a href="scripting#array-slice-to-end-note">slice to end</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>['a', 'b', 'c', 'd'].slice(1)</td>
<td>a[1:]</td>
<td>array_slice($a, 1)</td>
<td>a[1..-1]</td>
</tr>
<tr>
<td><a name="array-back" id="array-back"></a><a href="scripting#array-back-note">manipulate back</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>a = [6, 7, 8];<br />
a.push(9);<br />
i = a.pop();</td>
<td>a = [6, 7, 8]<br />
a.append(9)<br />
a.pop()</td>
<td>$a = [6, 7, 8];<br />
array_push($a, 9);<br />
$a[] = 9; <span style="color: gray"># same as array_push</span><br />
array_pop($a);</td>
<td>a = [6, 7, 8]<br />
a.push(9)<br />
a <span style="white-space: pre-wrap;">&lt;&lt;</span> 9 <span style="color: gray"># same as push</span><br />
a.pop</td>
</tr>
<tr>
<td><a name="array-front" id="array-front"></a><a href="scripting#array-front-note">manipulate front</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>a = [6, 7, 8];<br />
a.unshift(5);<br />
i = a.shift();</td>
<td>a = [6, 7, 8]<br />
a.insert(0, 5)<br />
a.pop(0)</td>
<td>$a = [6, 7, 8];<br />
array_unshift($a, 5);<br />
array_shift($a);</td>
<td>a = [6, 7, 8]<br />
a.unshift(5)<br />
a.shift</td>
</tr>
<tr>
<td><a name="array-concatenation" id="array-concatenation"></a><a href="scripting#array-concatenation-note">concatenate</a></td>
<td>a = [1, 2, 3].concat([4, 5, 6]);</td>
<td>a = [1, 2, 3]<br />
a2 = a + [4, 5, 6]<br />
a.extend([4, 5, 6])</td>
<td>$a = [1, 2, 3];<br />
$a2 = array_merge($a, [4, 5, 6]);<br />
$a = array_merge($a, [4, 5, 6]);</td>
<td>a = [1, 2, 3]<br />
a2 = a + [4, 5, 6]<br />
a.concat([4, 5, 6])</td>
</tr>
<tr>
<td><a name="replicate-array" id="replicate-array"></a><a href="scripting#replicate-array-note">replicate</a></td>
<td>Array(10).fill(null)</td>
<td>a = [None] * 10<br />
a = [None for i in range(0, 10)]</td>
<td>$a = array_fill(0, 10, NULL);</td>
<td>a = [nil] * 10<br />
a = Array.new(10, nil)</td>
</tr>
<tr>
<td><a name="array-copy" id="array-copy"></a><a href="scripting#array-copy-note">copy</a><br />
<span style="color: gray"><em>address copy, shallow copy, deep copy</em></span></td>
<td>a = [1, 2, [3, 4]];<br />
a2 = a;<br />
a3 = a.slice(0);<br />
a4 = JSON.parse(JSON.stringify(a));</td>
<td>import copy<br />
<br />
a = [1,2,[3,4]]<br />
a2 = a<br />
a3 = list(a)<br />
a4 = copy.deepcopy(a)</td>
<td>$a = [1, 2, [3, 4]];<br />
$a2 =&amp; $a;<br />
<span style="color: gray"><em>none</em></span><br />
$a4 = $a;</td>
<td>a = [1,2,[3,4]]<br />
a2 = a<br />
a3 = a.dup<br />
a4 = Marshal.load(Marshal.dump(a))</td>
</tr>
<tr>
<td><a name="array-as-func-arg" id="array-as-func-arg"></a><a href="scripting#array-as-func-arg-note">array as function argument</a></td>
<td><span style="color: gray"><em>parameter contains address copy</em></span></td>
<td><span style="color: gray"><em>parameter contains address copy</em></span></td>
<td><span style="color: gray"><em>parameter contains deep copy</em></span></td>
<td><span style="color: gray"><em>parameter contains address copy</em></span></td>
</tr>
<tr>
<td><a name="iterate-over-array" id="iterate-over-array"></a><a href="scripting#iterate-over-array-note">iterate over elements</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>[6, 7, 8].forEach((n) =&gt; {<br />
<span style="white-space: pre-wrap;">  </span>console.log(n);<br />
});<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> new in ES6:</span><br />
for (let n of [6, 7, 8]) {<br />
<span style="white-space: pre-wrap;">  </span>console.log(n);<br />
}</td>
<td>for i in [1, 2, 3]:<br />
<span style="white-space: pre-wrap;">  </span>print(i)</td>
<td>foreach ([1, 2, 3] as $i) {<br />
<span style="white-space: pre-wrap;">  </span>echo "$i\n";<br />
}</td>
<td>[1, 2, 3].each { |i| puts i }</td>
</tr>
<tr>
<td><a name="indexed-array-iteration" id="indexed-array-iteration"></a><a href="scripting#indexed-array-iteration-note">iterate over indices and elements</a></td>
<td>for (let i = 0; i &lt; a.length; ++i) {<br />
<span style="white-space: pre-wrap;">  </span>console.log(a[i]);<br />
}<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> indices not guaranteed to be in order:</span><br />
for (let i in a) {<br />
<span style="white-space: pre-wrap;">  </span>console.log(a[i]);<br />
}</td>
<td>a = ['do', 're', 'mi', 'fa']<br />
for i, s in enumerate(a):<br />
<span style="white-space: pre-wrap;">  </span>print('%s at index %d' % (s, i))</td>
<td>$a = ["do", "re", "mi" "fa"];<br />
foreach ($a as $i =&gt; $s) {<br />
<span style="white-space: pre-wrap;">  </span>echo "$s at index $i\n";<br />
}</td>
<td>a = %w(do re mi fa)<br />
a.each_with_index do |s, i|<br />
<span style="white-space: pre-wrap;">  </span>puts "#{s} at index #{i}"<br />
end</td>
</tr>
<tr>
<td><a name="range-iteration" id="range-iteration"></a><a href="scripting#range-iteration-note">iterate over range</a></td>
<td><span style="color: gray"><em>not space efficient; use C-style for loop</em></span></td>
<td><span style="color: gray"># use range() in Python 3:</span><br />
for i in xrange(1, 1000001):<br />
<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>code</em></span></td>
<td><span style="color: gray"><em>not space efficient; use C-style for loop</em></span></td>
<td>(1..1_000_000).each do |i|<br />
<span style="white-space: pre-wrap;">  </span><span style="color: gray"><em>code</em></span><br />
end</td>
</tr>
<tr>
<td><a name="range-array" id="range-array"></a><a href="scripting#range-array-note">instantiate range as array</a></td>
<td>let a = _.range(1, 11);</td>
<td>a = range(1, 11)<br />
<span style="color: gray"><em>Python 3:</em></span><br />
a = list(range(1, 11))</td>
<td>$a = range(1, 10);</td>
<td>a = (1..10).to_a</td>
</tr>
<tr>
<td><a name="array-reverse" id="array-reverse"></a><a href="scripting#array-reverse-note">reverse</a><br />
<span style="color: gray"><em>non-destructive, in-place</em></span></td>
<td>let a = [1, 2, 3];<br />
<br />
let a2 = a.slice(0).reverse();<br />
a.reverse();</td>
<td>a = [1, 2, 3]<br />
<br />
a[::-1]<br />
a.reverse()</td>
<td>$a = [1, 2, 3];<br />
<br />
array_reverse($a);<br />
$a = array_reverse($a);</td>
<td>a = [1, 2, 3]<br />
<br />
a.reverse<br />
a.reverse!</td>
</tr>
<tr>
<td><a name="array-sort" id="array-sort"></a><a href="scripting#array-sort-note">sort</a><br />
<span style="color: gray"><em>non-destructive,<br />
in-place,<br />
custom comparision</em></span></td>
<td>let a = [3, 1, 4, 2];<br />
<br />
let a2 = a.slice(0).sort();<br />
a.sort();</td>
<td>a = ['b', 'A', 'a', 'B']<br />
<br />
sorted(a)<br />
a.sort()<br />
<span style="color: gray"># custom binary comparision<br />
# removed from Python 3:</span><br />
a.sort(key=str.lower)</td>
<td>$a = ["b", "A", "a", "B"];<br />
<br />
<span style="color: gray"><em>none</em></span><br />
sort($a);<br />
<span style="color: gray"><em>none, but</em> usort <em>sorts in place</em></span></td>
<td>a = %w(b A a B)<br />
<br />
a.sort<br />
a.sort!<br />
a.sort do |x, y|<br />
<span style="white-space: pre-wrap;">  </span>x.downcase &lt;=&gt; y.downcase<br />
end</td>
</tr>
<tr>
<td><a name="array-dedupe" id="array-dedupe"></a><a href="scripting#array-dedupe-note">dedupe</a><br />
<span style="color: gray"><em>non-destructive, in-place</em></span></td>
<td>let a = [1, 2, 2, 3];<br />
<br />
let a2 = _.uniq(a);<br />
a = _.uniq(a);</td>
<td>a = [1, 2, 2, 3]<br />
<br />
a2 = list(set(a))<br />
a = list(set(a))</td>
<td>$a = [1, 2, 2, 3];<br />
<br />
$a2 = array_unique($a);<br />
$a = array_unique($a);</td>
<td>a = [1, 2, 2, 3]<br />
<br />
a2 = a.uniq<br />
a.uniq!</td>
</tr>
<tr>
<td><a name="membership" id="membership"></a><a href="scripting#membership-note">membership</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>a.includes(7)</td>
<td>7 in a</td>
<td>in_array(7, $a)</td>
<td>a.include?(7)</td>
</tr>
<tr>
<td><a name="intersection" id="intersection"></a><a href="scripting#intersection-note">intersection</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>_.intersection([1, 2], [2, 3, 4])</td>
<td>{1, 2} &amp; {2, 3, 4}</td>
<td>$a = [1, 2];<br />
$b = [2, 3, 4]<br />
array_intersect($a, $b)</td>
<td>[1, 2] &amp; [2 ,3, 4]</td>
</tr>
<tr>
<td><a name="union" id="union"></a><a href="scripting#union-note">union</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>_.union([1, 2], [2, 3, 4])</td>
<td>{1, 2} | {2, 3, 4}</td>
<td>$a1 = [1, 2];<br />
$a2 = [2, 3, 4];<br />
array_unique(array_merge($a1, $a2))</td>
<td>[1, 2] | [2, 3, 4]</td>
</tr>
<tr>
<td><a name="set-diff" id="set-diff"></a><a href="scripting#set-diff-note">relative complement, symmetric difference</a></td>
<td>_.difference([1, 2, 3], [2])<br />
<span style="color: gray"><em>none</em></span></td>
<td>{1, 2, 3} - {2}<br />
{1, 2} ^ {2, 3, 4}</td>
<td>$a1 = [1, 2, 3];<br />
$a2 = [2];<br />
array_values(array_diff($a1, $a2))<br />
<span style="color: gray"><em>none</em></span></td>
<td>require 'set'<br />
<br />
[1, 2, 3] - [2]<br />
Set[1, 2] ^ Set[2 ,3, 4]</td>
</tr>
<tr>
<td><a name="map" id="map"></a><a href="scripting#map-note">map</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> callback gets 3 args:<br />
<span style="white-space: pre-wrap;">//</span> value, index, array</span><br />
a.map((x) =&gt; x * x)</td>
<td>map(lambda x: x * x, [1, 2, 3])<br />
<span style="color: gray"># or use list comprehension:</span><br />
[x * x for x in [1, 2, 3]]</td>
<td>array_map(function ($x) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>return $x * $x;<br />
<span style="white-space: pre-wrap;">  </span>}, [1, 2, 3])</td>
<td>[1, 2, 3].map { |o| o * o }</td>
</tr>
<tr>
<td><a name="filter" id="filter"></a><a href="scripting#filter-note">filter</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>a.filter((x) =&gt; x &gt; 1)</td>
<td>filter(lambda x: x &gt; 1, [1, 2, 3])<br />
<span style="color: gray"># or use list comprehension:</span><br />
[x for x in [1, 2, 3] if x &gt; 1]</td>
<td>array_filter([1, 2, 3],<br />
<span style="white-space: pre-wrap;">  </span>function ($x) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>return $x&gt;1;<br />
<span style="white-space: pre-wrap;">  </span>})</td>
<td>[1, 2, 3].select { |o| o &gt; 1 }</td>
</tr>
<tr>
<td><a name="reduce" id="reduce"></a><a href="scripting#reduce-note">reduce</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>a.reduce((m, o) =&gt; m + o, 0)</td>
<td><span style="color: gray"># import needed in Python 3 only</span><br />
from functools import reduce<br />
<br />
reduce(lambda x, y: x + y, [1, 2, 3], 0)</td>
<td>array_reduce([1, 2, 3],<br />
<span style="white-space: pre-wrap;">  </span>function($x,$y) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>return $x + $y;<br />
<span style="white-space: pre-wrap;">  </span>}, 0)</td>
<td>[1, 2, 3].inject(0) { |m, o| m + o }</td>
</tr>
<tr>
<td><a name="universal-existential-test" id="universal-existential-test"></a><a href="scripting#universal-existential-test-note">universal and existential tests</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>let a = [1, 2, 3, 4];<br />
<br />
a.every((n) =&gt; n % 2 === 0)<br />
a.some((n) =&gt; n % 2 === 0)</td>
<td>all(i % 2 == 0 for i in [1, 2, 3, 4])<br />
any(i % 2 == 0 for i in [1, 2, 3, 4])</td>
<td><span style="color: gray"><em>use array_filter</em></span></td>
<td>[1, 2, 3, 4].all? {|i| i.even? }<br />
[1, 2, 3, 4].any? {|i| i.even? }</td>
</tr>
<tr>
<td><a name="shuffle-sample" id="shuffle-sample"></a><a href="scripting#shuffle-sample-note">shuffle and sample</a></td>
<td>let a = [1, 2, 3, 4];<br />
<br />
a = _.shuffle(a);<br />
let samp = _.sampleSize([1, 2, 3, 4], 2);</td>
<td>from random import shuffle, sample<br />
<br />
a = [1, 2, 3, 4]<br />
shuffle(a)<br />
samp = sample([1, 2, 3, 4], 2)</td>
<td>$a = [1, 2, 3, 4];<br />
<br />
shuffle($a);<br />
$samp = array_rand(|[1, 2, 3, 4], 2);</td>
<td>[1, 2, 3, 4].shuffle!<br />
samp = [1, 2, 3, 4].sample(2)</td>
</tr>
<tr>
<td><a name="flatten" id="flatten"></a><a href="scripting#flatten-note">flatten</a><br />
<span style="color: gray"><em>one level, completely</em></span></td>
<td>let a = [1, [2, [3, 4]]];<br />
<br />
let a2 = _.flatten(a);<br />
let a3 = _.flattenDeep(a);</td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>a = [1, [2, [3, 4]]]<br />
a2 = a.flatten(1)<br />
a3 = a.flatten</td>
</tr>
<tr>
<td><a name="zip" id="zip"></a><a href="scripting#zip-note">zip</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>let a = _.zip([1, 2, 3], ['a', 'b', 'c']);<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> shorter array padded with undefined:</span><br />
_.zip([1, 2, 3], ['a', 'b'])</td>
<td>list(zip([1, 2, 3], ['a', 'b', 'c']))<br />
<br />
<span style="color: gray"># extras in longer array dropped:</span><br />
list(zip([1, 2, 3], ['a', 'b']))</td>
<td>$a = array_map(NULL,<br />
<span style="white-space: pre-wrap;">  </span>[1, 2, 3],<br />
<span style="white-space: pre-wrap;">  </span>["a", "b", "c"]);<br />
<br />
<span style="color: gray"># shorter array padded with NULLs</span></td>
<td>[1, 2, 3].zip(["a", "b", "c"])<br />
<br />
<span style="color: gray"># shorter array padded with nil:</span><br />
[1, 2, 3].zip(["a", "b"])</td>
</tr>
<tr>
<th colspan="5"><a name="dictionaries" id="dictionaries"></a><a href="scripting#dictionaries-note">dictionaries</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="dict-literal" id="dict-literal"></a><a href="scripting#dict-literal-note">literal</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>d = {t: 1, f: 0};<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> keys do not need to be quoted if they<br />
<span style="white-space: pre-wrap;">//</span> are a legal JavaScript variable name<br />
<span style="white-space: pre-wrap;">//</span> and not a reserved word</span></td>
<td>d = {'t': 1, 'f': 0}</td>
<td>$d = ["t" =&gt; 1, "f" =&gt; 0];<br />
<br />
<span style="color: gray"># older syntax:</span><br />
$d = array("t" =&gt; 1, "f" =&gt; 0);</td>
<td>d = {'t' =&gt; 1, 'f' =&gt; 0}<br />
<br />
<span style="color: gray"># keys are symbols:</span><br />
symbol_to_int = {t: 1, f: 0}</td>
</tr>
<tr>
<td><a name="dict-size" id="dict-size"></a><a href="scripting#dict-size-note">size</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>_.size(d)<br />
Object.getOwnPropertyNames(d).length</td>
<td>len(d)</td>
<td>count($d)</td>
<td>d.size<br />
d.length</td>
</tr>
<tr>
<td><a name="dict-lookup" id="dict-lookup"></a><a href="scripting#dict-lookup-note">lookup</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>d.hasOwnProperty("t") ? d["t"] : undefined<br />
d.hasOwnProperty("t") ? d.t : undefined<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> JavaScript dictionaries are objects<br />
<span style="white-space: pre-wrap;">//</span> and inherit properties from Object.</span></td>
<td>d['t']</td>
<td>$d["t"]</td>
<td>d['t']</td>
</tr>
<tr>
<td><a name="dict-update" id="dict-update"></a><a href="scripting#dict-update-note">update</a></td>
<td>d['t'] = 2;<br />
d.t = 2;</td>
<td>d['t'] = 2<br />
<br />
<span style="color: gray"># provide default to avoid KeyError:</span><br />
d.get('t', None)</td>
<td>$d["t"] = 2;</td>
<td>d['t'] = 2</td>
</tr>
<tr>
<td><a name="dict-missing-key" id="dict-missing-key"></a><a href="scripting#dict-missing-key-note">missing key behavior</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>let d = {};<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> undefined:</span><br />
d["lorem"];<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> adds key/value pair:</span><br />
d["lorem"] = "ipsum";</td>
<td>d = {}<br />
<span style="color: gray"># raises KeyError:</span><br />
d['lorem']<br />
<span style="color: gray"># adds key/value pair:</span><br />
d['lorem'] = 'ipsum'</td>
<td>$d = [];<br />
<span style="color: gray"># NULL:</span><br />
$d["lorem"];<br />
<span style="color: gray"># adds key/value pair:</span><br />
$d["lorem"] = "ipsum";</td>
<td>d = {}<br />
<span style="color: gray"># nil:</span><br />
d['lorem']<br />
<span style="color: gray"># adds key/value pair:</span><br />
d['lorem'] = 'ipsum'</td>
</tr>
<tr>
<td><a name="dict-key-check" id="dict-key-check"></a><a href="scripting#dict-key-check-note">is key present</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>d.hasOwnProperty("t");</td>
<td>'y' in d</td>
<td>array_key_exists("y", $d);</td>
<td>d.key?('y')</td>
</tr>
<tr>
<td><a name="dict-delete" id="dict-delete"></a><a href="scripting#dict-delete-note">delete</a></td>
<td>delete d["t"];<br />
delete d.t;</td>
<td>d = {1: True, 0: False}<br />
del d[1]</td>
<td>$d = [1 =&gt; "t", 0 =&gt; "f"];<br />
unset($d[1]);</td>
<td>d = {1 =&gt; true, 0 =&gt; false}<br />
d.delete(1)</td>
</tr>
<tr>
<td><a name="dict-assoc-array" id="dict-assoc-array"></a><a href="scripting#dict-assoc-array-note">from array of pairs, from even length array</a></td>
<td>let a = [['a', 1], ['b', 2], ['c', 3]];<br />
let d = _.fromPairs(a);<br />
<br />
<span style="color: gray"><em>none</em></span></td>
<td>a = [['a', 1], ['b', 2], ['c', 3]]<br />
d = dict(a)<br />
<br />
a = ['a', 1, 'b', 2, 'c', 3]<br />
d = dict(zip(a[::2], a[1::2]))</td>
<td></td>
<td>a = [['a', 1], ['b', 2], ['c', 3]]<br />
d = Hash[a]<br />
<br />
a = ['a', 1, 'b', 2, 'c', 3]<br />
d = Hash[*a]</td>
</tr>
<tr>
<td><a name="dict-merge" id="dict-merge"></a><a href="scripting#dict-merge-note">merge</a></td>
<td>let d1 = {a: 1, b: 2};<br />
let d2 = {b: 3, c: 4};<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> d2 overwrites shared keys in d1:</span><br />
d1 = _.assignIn(d1, d2);</td>
<td>d1 = {'a': 1, 'b': 2}<br />
d2 = {'b': 3, 'c': 4}<br />
d1.update(d2)</td>
<td>$d1 = ["a" =&gt; 1, "b" =&gt; 2];<br />
$d2 = ["b" =&gt; 3, "c" =&gt; 4];<br />
$d1 = array_merge($d1, $d2);</td>
<td>d1 = {'a' =&gt; 1, 'b' =&gt; 2}<br />
d2 = {'b' =&gt; 3, 'c' =&gt; 4}<br />
d1.merge!(d2)</td>
</tr>
<tr>
<td><a name="dict-invert" id="dict-invert"></a><a href="scripting#dict-invert-note">invert</a></td>
<td>let let2num = {t: 1, f: 0};<br />
let num2let = _.invert(let2num);</td>
<td>to_num = {'t': 1, 'f': 0}<br />
<span style="color: gray"># dict comprehensions added in 2.7:</span><br />
to_let = {v: k for k, v<br />
<span style="white-space: pre-wrap;">  </span>in to_num.items()}</td>
<td>$to_num = ["t" =&gt; 1, "f" =&gt; 0];<br />
$to_let = array_flip($to_num);</td>
<td>to_num = {'t' =&gt; 1, 'f' =&gt; 0}<br />
to_let = to_num.invert</td>
</tr>
<tr>
<td><a name="dict-iter" id="dict-iter"></a><a href="scripting#dict-iter-note">iterate</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>for (let k in d) {<br />
<span style="white-space: pre-wrap;">  </span>console.log(<span style="white-space: pre-wrap;">`</span>value at ${k} is ${d[k]}<span style="white-space: pre-wrap;">`</span>);<br />
}</td>
<td>for k, v in d.items():<br />
<span style="white-space: pre-wrap;">  </span>print('value at {} is {}'.format(k, v)<br />
<br />
<span style="color: gray"># Python 2: use iteritems()</span></td>
<td>foreach ($d as $k =&gt; $v) {<br />
<span style="white-space: pre-wrap;">  </span>echo "value at ${k} is ${v}";<br />
}</td>
<td>d.each do |k,v|<br />
<span style="white-space: pre-wrap;">  </span>puts "value at #{k} is #{v}"<br />
end</td>
</tr>
<tr>
<td><a name="dict-key-val" id="dict-key-val"></a><a href="scripting#dict-key-val-note">keys and values as arrays</a></td>
<td>Object.keys(d)<br />
_.values(d)</td>
<td>list(d.keys())<br />
list(d.values())<br />
<br />
<span style="color: gray"># keys() and values return iterators<br />
# in Python 3 and lists in Python 2</span></td>
<td>array_keys($d)<br />
array_values($d)</td>
<td>d.keys<br />
d.values</td>
</tr>
<tr>
<td><a name="dict-sort-values" id="dict-sort-values"></a><a href="scripting#dict-sort-values-note">sort by values</a></td>
<td>let cmp = (a, b) =&gt; a[1] - b[1];<br />
let d = {t: 1, f: 0};<br />
<br />
for (let p of _.toPairs(d).sort(cmp)) {<br />
<span style="white-space: pre-wrap;">  </span>console.log(p);<br />
}</td>
<td>from operator import itemgetter<br />
<br />
pairs = sorted(d.items(), key=itemgetter(1))<br />
<br />
for k, v in pairs:<br />
<span style="white-space: pre-wrap;">  </span>print('{}: {}'.format(k, v))</td>
<td>asort($d);<br />
<br />
foreach ($d as $k =&gt; $v) {<br />
<span style="white-space: pre-wrap;">  </span>print "$k: $v\n";<br />
}</td>
<td>d.sort_by { |k, v| v }.each do |k, v|<br />
<span style="white-space: pre-wrap;">  </span>puts "#{k}: #{v}"<br />
end</td>
</tr>
<tr>
<td><a name="dict-default-val" id="dict-default-val"></a><a href="scripting#dict-default-val-note">default value, computed value</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>from collections import defaultdict<br />
<br />
counts = defaultdict(lambda: 0)<br />
counts['foo'] += 1<br />
<br />
class Factorial(dict):<br />
<span style="white-space: pre-wrap;">  </span>def <span style="white-space: pre-wrap;">__missing__</span>(self, k):<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>if k &gt; 1:<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>return k * self[k-1]<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>else:<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>return 1<br />
<br />
factorial = Factorial()</td>
<td>$counts = [];<br />
$counts['foo'] += 1;<br />
<br />
<span style="color: gray"># For computed values and defaults other than<br />
# zero or empty string, extend ArrayObject.</span></td>
<td>counts = Hash.new(0)<br />
counts['foo'] += 1<br />
<br />
factorial = Hash.new do |h,k|<br />
<span style="white-space: pre-wrap;">  </span>k &gt; 1 ? k * h[k-1] : 1<br />
end</td>
</tr>
<tr>
<th colspan="5"><a name="functions" id="functions"></a><a href="scripting#functions-note">functions</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="def-func" id="def-func"></a><a href="scripting#def-func-note">define</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>function add3 (x1, x2, x3) {<br />
<span style="white-space: pre-wrap;">  </span>return x1 + x2 + x3;<br />
}</td>
<td>def add3(x1, x2, x3):<br />
<span style="white-space: pre-wrap;">  </span>return x1 + x2 + x3</td>
<td>function add3($x1, $x2, $x3)<br />
{<br />
<span style="white-space: pre-wrap;">  </span>return $x1 + $x2 + $x3;<br />
}</td>
<td>def add3(x1, x2, x3)<br />
<span style="white-space: pre-wrap;">  </span>x1 + x2 + x3<br />
end<br />
<br />
<span style="color: gray"># parens are optional and customarily<br />
# omitted when defining functions<br />
# with no parameters</span></td>
</tr>
<tr>
<td><a name="invoke-func" id="invoke-func"></a><a href="scripting#invoke-func-note">invoke</a></td>
<td>add3(1, 2, 3)</td>
<td>add3(1, 2, 3)</td>
<td>add3(1, 2, 3);<br />
<br />
<span style="color: gray"># function names are case insensitive:</span><br />
ADD3(1, 2, 3);</td>
<td>add3(1, 2, 3)<br />
<br />
<span style="color: gray"># parens are optional:</span><br />
add3 1, 2, 3</td>
</tr>
<tr>
<td><a name="missing-arg" id="missing-arg"></a><a href="scripting#missing-arg-note">missing argument behavior</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>set to</em> undefined</span></td>
<td><span style="color: gray"><em>raises</em> TypeError <em>if number of arguments doesn't match function arity</em></span></td>
<td><span style="color: gray"><em>set to</em> NULL <em>with warning</em></span></td>
<td><span style="color: gray"><em>raises</em> ArgumentError <em>if number of arguments doesn't match function arity</em></span></td>
</tr>
<tr>
<td><a name="extra-arg" id="extra-arg"></a><a href="scripting#extra-arg-note">extra argument behavior</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>ignored</em></span></td>
<td><span style="color: gray"><em>raises</em> TypeError <em>if number of arguments doesn't match function arity</em></span></td>
<td><span style="color: gray"><em>ignored</em></span></td>
<td><span style="color: gray"><em>raises</em> ArgumentError <em>if number of arguments doesn't match function arity</em></span></td>
</tr>
<tr>
<td><a name="default-arg" id="default-arg"></a><a href="scripting#default-arg-note">default argument</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><span style="white-space: pre-wrap;">//</span> new in ES6:</span><br />
function myLog (x, base = 10) {<br />
<span style="white-space: pre-wrap;">  </span>return Math.log(x) / Math.log(base);<br />
}</td>
<td>import math<br />
<br />
def my_log(x, base=10):<br />
<span style="white-space: pre-wrap;">  </span>return math.log(x) / math.log(base)<br />
<br />
my_log(42)<br />
my_log(42, math.e)</td>
<td>function my_log($x, $base=10)<br />
{<br />
<span style="white-space: pre-wrap;">  </span>return log($x) / log($base);<br />
}<br />
<br />
my_log(42);<br />
my_log(42, M_E);</td>
<td>def my_log(x, base=10)<br />
<span style="white-space: pre-wrap;">  </span>Math.log(x) / Math.log(base)<br />
end<br />
<br />
my_log(42)<br />
my_log(42, Math::E)</td>
</tr>
<tr>
<td><a name="variadic-func" id="variadic-func"></a><a href="scripting#variadic-func-note">variadic function</a></td>
<td>function firstAndLast() {<br />
<span style="white-space: pre-wrap;">  </span>if (arguments.length &gt;= 1) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>console.log('first: ' + arguments[0]);<br />
<span style="white-space: pre-wrap;">  </span>}<br />
<span style="white-space: pre-wrap;">  </span>if (arguments.length &gt;= 2) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>console.log('last: ' + arguments[1]);<br />
<span style="white-space: pre-wrap;">  </span>}<br />
}<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">// ...</span> operator new in ES6:</span><br />
function firstAndLast(<span style="white-space: pre-wrap;">...</span>a) {<br />
<span style="white-space: pre-wrap;">  </span>if (a.length &gt;= 1) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>console.log('first: ' + a[0]);<br />
<span style="white-space: pre-wrap;">  </span>}<br />
<span style="white-space: pre-wrap;">  </span>if (a.length &gt;= 2) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>console.log('last: ' + a[1]);<br />
<span style="white-space: pre-wrap;">  </span>}<br />
}</td>
<td>def first_and_last(*a):<br />
<br />
<span style="white-space: pre-wrap;">  </span>if len(a) &gt;= 1:<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>print('first: ' + str(a[0]))<br />
<br />
<span style="white-space: pre-wrap;">  </span>if len(a) &gt;= 2:<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>print('last: ' + str(a[-1]))</td>
<td>function first_and_last()<br />
{<br />
<br />
<span style="white-space: pre-wrap;">  </span>$arg_cnt = func_num_args();<br />
<br />
<span style="white-space: pre-wrap;">  </span>if ($arg_cnt &gt;= 1) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>$n = func_get_arg(0);<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>echo "first: " . $n . "\n";<br />
<span style="white-space: pre-wrap;">  </span>}<br />
<br />
<span style="white-space: pre-wrap;">  </span>if ($arg_cnt &gt;= 2) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>$a = func_get_args();<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>$n = $a[$arg_cnt-1];<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>echo "last: " . $n . "\n";<br />
<span style="white-space: pre-wrap;">  </span>}<br />
}</td>
<td>def first_and_last(*a)<br />
<br />
<span style="white-space: pre-wrap;">  </span>if a.size &gt;= 1<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>puts "first: #{a[0]}"<br />
<span style="white-space: pre-wrap;">  </span>end<br />
<br />
<span style="white-space: pre-wrap;">  </span>if a.size &gt;= 2<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>puts "last: #{a[-1]}"<br />
<span style="white-space: pre-wrap;">  </span>end<br />
end</td>
</tr>
<tr>
<td><a name="apply-func" id="apply-func"></a><a href="scripting#apply-func-note">pass array elements as separate arguments</a></td>
<td>let a = [1, 2, 3];<br />
<br />
let sum = add3(<span style="white-space: pre-wrap;">...</span>a);</td>
<td>a = [2, 3]<br />
<br />
add3(1, *a)<br />
<br />
<span style="color: gray"># splat operator can only be used once<br />
# and must appear after other<br />
# unnamed arguments</span></td>
<td>$a = [1, 2, 3];<br />
<br />
call_user_func_array("add3", $a);</td>
<td>a = [2, 3]<br />
<br />
add3(1, *a)<br />
<br />
<span style="color: gray"># splat operator can be used multiple<br />
# times and can appear before regular<br />
# arguments</span></td>
</tr>
<tr>
<td><a name="param-alias" id="param-alias"></a><a href="scripting#param-alias-note">parameter alias</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>function first_and_second(&amp;$a)<br />
{<br />
<span style="white-space: pre-wrap;">  </span>return [$a[0], $a[1]];<br />
}</td>
<td><span style="color: gray"><em>none</em></span></td>
</tr>
<tr>
<td><a name="named-param" id="named-param"></a><a href="scripting#named-param-note">named parameters</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>def fequal(x, y, eps=0.01):<br />
<span style="white-space: pre-wrap;">  </span>return abs(x - y) &lt; eps<br />
<br />
fequal(1.0, 1.001)<br />
fequal(1.0, 1.001, eps=0.1<span style="white-space: pre-wrap;">**</span>10)</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>def fequals(x, y, eps: 0.01)<br />
<span style="white-space: pre-wrap;">  </span>(x - y).abs &lt; eps<br />
end<br />
<br />
fequals(1.0, 1.001)<br />
fequals(1.0, 1.001, eps: 0.1**10)</td>
</tr>
<tr>
<td><a name="retval" id="retval"></a><a href="scripting#retval-note">return value</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray">return <em>arg or</em> undefined.</span><br />
<br />
<span style="color: gray"><em>If invoked with</em> new <em>and</em> return <em>value not an object, returns</em> this.</span></td>
<td><span style="color: gray">return <em>arg or</em> None</span></td>
<td><span style="color: gray">return <em>arg or</em> NULL</span></td>
<td><span style="color: gray">return <em>arg or last expression evaluated</em></span></td>
</tr>
<tr>
<td><a name="multiple-retval" id="multiple-retval"></a><a href="scripting#multiple-retval-note">multiple return values</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>function firstAndSecond(a) {<br />
<span style="white-space: pre-wrap;">  </span>return [a[0], a[1]];<br />
}<br />
<br />
let [x, y] = firstAndSecond([6, 7, 8]);<br /></td>
<td>def first_and_second(a):<br />
<span style="white-space: pre-wrap;">  </span>return a[0], a[1]<br />
<br />
x, y = first_and_second([6, 7, 8])</td>
<td>function first_and_second(&amp;$a)<br />
{<br />
<span style="white-space: pre-wrap;">  </span>return [$a[0], $a[1]];<br />
}<br />
<br />
$a = [6, 7, 8];<br />
list($x, $y) =<br />
<span style="white-space: pre-wrap;">  </span>first_and_second($a);</td>
<td>def first_and_second(a)<br />
<span style="white-space: pre-wrap;">  </span>return a[0], a[1]<br />
end<br />
<br />
x, y = first_and_second([6, 7, 8])</td>
</tr>
<tr>
<td><a name="anonymous-func-literal" id="anonymous-func-literal"></a><a href="scripting#anonymous-func-literal-note">anonymous function literal</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>let square = function (x) {<br />
<span style="white-space: pre-wrap;">  </span>return x * x;<br />
};<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> =&gt; new in ES6:</span><br />
let square = (x) =&gt; { return x * x; };<br />
<br />
<span style="color: gray"><span style="white-space: pre-wrap;">//</span> expression body variant:</span><br />
let square = (x) =&gt; x * x;</td>
<td><span style="color: gray"># body must be an expression:</span><br />
square = lambda x: x * x</td>
<td>$square = function ($x) {<br />
<span style="white-space: pre-wrap;">  </span>return $x * $x;<br />
};</td>
<td>square = lambda { |x| x * x }</td>
</tr>
<tr>
<td><a name="invoke-anonymous-func" id="invoke-anonymous-func"></a><a href="scripting#invoke-anonymous-func-note">invoke anonymous function</a></td>
<td>square(2)<br />
<br />
((x) =&gt; (x * x)(2)</td>
<td>square(2)<br />
<br />
(lambda x: x * x)(2)</td>
<td>$square(2)</td>
<td>square.call(2)<br />
<br />
<span style="color: gray"># alternative syntax:</span><br />
square[2]</td>
</tr>
<tr>
<td><a name="func-as-val" id="func-as-val"></a><a href="scripting#func-as-val-note">function as value</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>let func = add3;</td>
<td>func = add3</td>
<td>$func = "add3";</td>
<td>func = lambda { |*args| add3(*args) }</td>
</tr>
<tr>
<td><a name="private-state-func" id="private-state-func"></a><a href="scripting#private-state-func-note">function with private state</a></td>
<td>function counter() {<br />
<span style="white-space: pre-wrap;">  </span>counter.i += 1;<br />
<span style="white-space: pre-wrap;">  </span>return counter.i;<br />
}<br />
<br />
counter.i = 0;<br />
console.log(counter());</td>
<td><span style="color: gray"># state not private:</span><br />
def counter():<br />
<span style="white-space: pre-wrap;">  </span>counter.i += 1<br />
<span style="white-space: pre-wrap;">  </span>return counter.i<br />
<br />
counter.i = 0<br />
print(counter())</td>
<td>function counter()<br />
{<br />
<span style="white-space: pre-wrap;">  </span>static $i = 0;<br />
<span style="white-space: pre-wrap;">  </span>return ++$i;<br />
}<br />
<br />
echo counter();</td>
<td><span style="color: gray"><em>none</em></span></td>
</tr>
<tr>
<td><a name="closure" id="closure"></a><a href="scripting#closure-note">closure</a></td>
<td>function makeCounter () {<br />
<span style="white-space: pre-wrap;">  </span>let i = 0;<br />
<br />
<span style="white-space: pre-wrap;">  </span>return function () {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>i += 1;<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>return i;<br />
<span style="white-space: pre-wrap;">  </span>};<br />
}<br />
<br />
let nays = makeCounter();<br />
console.log(nays());</td>
<td>def make_counter():<br />
<span style="white-space: pre-wrap;">  </span>i = 0<br />
<span style="white-space: pre-wrap;">  </span>def counter():<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="color: gray"># new in Python 3:</span><br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>nonlocal i<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>i += 1<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>return i<br />
<span style="white-space: pre-wrap;">  </span>return counter<br />
<br />
nays = make_counter()<br />
print(nays())</td>
<td>function make_counter()<br />
{<br />
<span style="white-space: pre-wrap;">  </span>$i = 0;<br />
<span style="white-space: pre-wrap;">  </span>return function () use (&amp;$i) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>return ++$i;<br />
<span style="white-space: pre-wrap;">  </span>};<br />
}<br />
<br />
$nays = make_counter();<br />
echo $nays();</td>
<td>def make_counter<br />
<span style="white-space: pre-wrap;">  </span>i = 0<br />
<span style="white-space: pre-wrap;">  </span>return lambda { i +=1; i }<br />
end<br />
<br />
nays = make_counter<br />
puts nays.call</td>
</tr>
<tr>
<td><a name="generator" id="generator"></a><a href="scripting#generator-note">generator</a></td>
<td>function * makeCounter () {<br />
<span style="white-space: pre-wrap;">  </span>let i = 0;<br />
<span style="white-space: pre-wrap;">  </span>while (true) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>yield ++i;<br />
<span style="white-space: pre-wrap;">  </span>}<br />
}<br />
<br />
let nays = makeCounter();<br />
for (let cnt of nays) {<br />
<span style="white-space: pre-wrap;">  </span>console.log(cnt);<br />
<span style="white-space: pre-wrap;">  </span>if (cnt &gt; 100) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>break;<br />
<span style="white-space: pre-wrap;">  </span>}<br />
}</td>
<td><span style="color: gray"># cf. itertools library</span><br />
<br />
def make_counter():<br />
<span style="white-space: pre-wrap;">  </span>i = 0<br />
<span style="white-space: pre-wrap;">  </span>while True:<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>i += 1<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>yield i<br />
<br />
nays = make_counter()<br />
<span style="color: gray"># Python 2: nays.next()</span><br />
print(next(nays))<br />
<br />
for cnt in nays:<br />
<span style="white-space: pre-wrap;">  </span>print(cnt)<br />
<span style="white-space: pre-wrap;">  </span>if cnt &gt; 100:<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>break<br />
<br />
<span style="color: gray"># Returning without yielding raises<br />
# StopIteration exception.</span></td>
<td><span style="color: gray"># PHP 5.5:</span><br />
function make_counter() {<br />
<span style="white-space: pre-wrap;">  </span>$i = 0;<br />
<span style="white-space: pre-wrap;">  </span>while (1) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>yield ++$i;<br />
<span style="white-space: pre-wrap;">  </span>}<br />
}<br />
<br />
$nays = make_counter();<br />
<span style="color: gray"># does not return a value:</span><br />
$nays-&gt;next();<br />
<span style="color: gray"># runs generator if generator has not<br />
# yet yielded:</span><br />
echo $nays-&gt;current();</td>
<td>def make_counter<br />
<span style="white-space: pre-wrap;">  </span>return Fiber.new do<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>i = 0<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>while true<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>i += 1<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>Fiber.yield i<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>end<br />
<span style="white-space: pre-wrap;">  </span>end<br />
end<br />
<br />
nays = make_counter<br />
puts nays.resume</td>
</tr>
<tr>
<td><a name="decorator" id="decorator"></a><a href="scripting#decorator-note">decorator</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>def logcall(f):<br />
<span style="white-space: pre-wrap;">  </span>def wrapper(*a, **opts):<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>print('calling ' + f.<span style="white-space: pre-wrap;">__name__</span>)<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>f(*a, **opts)<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>print('called ' + f.<span style="white-space: pre-wrap;">__name__</span>)<br />
<span style="white-space: pre-wrap;">  </span>return wrapper<br />
<br />
@logcall<br />
def square(x):<br />
<span style="white-space: pre-wrap;">  </span>return x * x</td>
<td></td>
<td></td>
</tr>
<tr>
<td><a name="invoke-op-like-func" id="invoke-op-like-func"></a><a href="scripting#invoke-op-like-func-note">invoke operator like function</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>import operator<br />
<br />
operator.mul(3, 7)<br />
<br />
a = ['foo', 'bar', 'baz']<br />
operator.itemgetter(2)(a)</td>
<td></td>
<td>3.*(7)<br />
<br />
a = ['foo', 'bar', 'baz']<br />
a.[](2)</td>
</tr>
<tr>
<th colspan="5"><a name="execution-control" id="execution-control"></a><a href="scripting#execution-control-note">execution control</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="if" id="if"></a><a href="scripting#if-note">if</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>if (n === 0) {<br />
<span style="white-space: pre-wrap;">  </span>console.log('no hits');<br />
} else if (n === 1) {<br />
<span style="white-space: pre-wrap;">  </span>console.log('1 hit');<br />
} else {<br />
<span style="white-space: pre-wrap;">  </span>console.log(n + ' hits');<br />
}</td>
<td>if 0 == n:<br />
<span style="white-space: pre-wrap;">  </span>print('no hits')<br />
elif 1 == n:<br />
<span style="white-space: pre-wrap;">  </span>print('one hit')<br />
else:<br />
<span style="white-space: pre-wrap;">  </span>print(str(n) + ' hits')</td>
<td>if ( 0 == $n ) {<br />
<span style="white-space: pre-wrap;">  </span>echo "no hits\n";<br />
} elseif ( 1 == $n ) {<br />
<span style="white-space: pre-wrap;">  </span>echo "one hit\n";<br />
} else {<br />
<span style="white-space: pre-wrap;">  </span>echo "$n hits\n";<br />
}</td>
<td>if n == 0<br />
<span style="white-space: pre-wrap;">  </span>puts "no hits"<br />
elsif 1 == n<br />
<span style="white-space: pre-wrap;">  </span>puts "one hit"<br />
else<br />
<span style="white-space: pre-wrap;">  </span>puts "#{n} hits"<br />
end</td>
</tr>
<tr>
<td><a name="switch" id="switch"></a><a href="scripting#switch-note">switch</a></td>
<td>switch (n) {<br />
case 0:<br />
<span style="white-space: pre-wrap;">  </span>console.log('no hits\n;);<br />
<span style="white-space: pre-wrap;">  </span>break;<br />
case 1:<br />
<span style="white-space: pre-wrap;">  </span>console.log('one hit\n');<br />
<span style="white-space: pre-wrap;">  </span>break;<br />
default:<br />
<span style="white-space: pre-wrap;">  </span>console.log(n + ' hits\n');<br />
}</td>
<td><span style="color: gray"><em>none</em></span></td>
<td>switch ($n) {<br />
case 0:<br />
<span style="white-space: pre-wrap;">  </span>echo "no hits\n";<br />
<span style="white-space: pre-wrap;">  </span>break;<br />
case 1:<br />
<span style="white-space: pre-wrap;">  </span>echo "one hit\n";<br />
<span style="white-space: pre-wrap;">  </span>break;<br />
default:<br />
<span style="white-space: pre-wrap;">  </span>echo "$n hits\n";<br />
}</td>
<td>case n<br />
when 0<br />
<span style="white-space: pre-wrap;">  </span>puts "no hits"<br />
when 1<br />
<span style="white-space: pre-wrap;">  </span>puts "one hit"<br />
else<br />
<span style="white-space: pre-wrap;">  </span>puts "#{n} hits"<br />
end</td>
</tr>
<tr>
<td><a name="while" id="while"></a><a href="scripting#while-note">while</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>while (i &lt; 100) {<br />
<span style="white-space: pre-wrap;">  </span>i += 1;<br />
}</td>
<td>while i &lt; 100:<br />
<span style="white-space: pre-wrap;">  </span>i += 1</td>
<td>while ( $i &lt; 100 ) { $i++; }</td>
<td>while i &lt; 100 do<br />
<span style="white-space: pre-wrap;">  </span>i += 1<br />
end</td>
</tr>
<tr>
<td><a name="for" id="for"></a><a href="scripting#for-note">for</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>for (let i = 0; i &lt; 10; ++i) {<br />
<span style="white-space: pre-wrap;">  </span>console.log(i);<br />
}</td>
<td>for i in range(1, 11):<br />
<span style="white-space: pre-wrap;">  </span>print(i)</td>
<td>for ($i = 1; $i &lt;= 10; $i++) {<br />
<span style="white-space: pre-wrap;">  </span>echo "$i\n";<br />
}</td>
<td><span style="color: gray"><em>none</em></span></td>
</tr>
<tr>
<td><a name="break" id="break"></a><a href="scripting#break-note">break</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>for (let i = 30; i &lt; 50; ++i) {<br />
<span style="white-space: pre-wrap;">  </span>if (i % 7 === 0) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>console.log('first multiple: ' + i);<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>break;<br />
<span style="white-space: pre-wrap;">  </span>}<br />
}</td>
<td>break</td>
<td>break</td>
<td>break</td>
</tr>
<tr>
<td><a name="continue" id="continue"></a><a href="scripting#continue-note">continue</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>for (let i = 30; i &lt; 50; ++i) {<br />
<span style="white-space: pre-wrap;">  </span>if (i % 7 === 0) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>continue;<br />
<span style="white-space: pre-wrap;">  </span>}<br />
<span style="white-space: pre-wrap;">  </span>console.log('not divisible: ' + i);<br />
}</td>
<td>continue</td>
<td>continue</td>
<td>next</td>
</tr>
<tr>
<td><a name="statement-modifiers" id="statement-modifiers"></a><a href="scripting#statement-modifiers-note">statement modifiers</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td>puts "positive" if i &gt; 0<br />
puts "nonzero" unless i == 0</td>
</tr>
<tr>
<th colspan="5"><a name="exceptions" id="exceptions"></a><a href="scripting#exceptions-note">exceptions</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="base-exc" id="base-exc"></a><a href="scripting#base-exc-note">base exception</a></td>
<td><span style="color: gray"><em>Any value can be thrown.</em></span></td>
<td>BaseException<br />
<br />
<span style="color: gray"><em>User-defined exceptions should subclass</em> Exception.</span><br />
<br />
<span style="color: gray"><em>In Python 2 old-style classes can be thrown.</em></span></td>
<td>Exception</td>
<td>Exception<br />
<br />
<span style="color: gray"><em>User-defined exceptions should subclass</em> StandardError.</span></td>
</tr>
<tr>
<td><a name="predefined-exc" id="predefined-exc"></a><a href="scripting#predefined-exc-note">predefined exceptions</a></td>
<td>Error<br />
<span style="white-space: pre-wrap;">  </span>EvalError<br />
<span style="white-space: pre-wrap;">  </span>RangeError<br />
<span style="white-space: pre-wrap;">  </span>ReferenceError<br />
<span style="white-space: pre-wrap;">  </span>SyntaxError<br />
<span style="white-space: pre-wrap;">  </span>TypeError<br />
<span style="white-space: pre-wrap;">  </span>URIError</td>
<td>BaseException<br />
<span style="white-space: pre-wrap;">  </span>Exception<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>TypeError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>ImportError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>AssertionError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>ArithmeticError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>FloatingPointError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>OverflowError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>ZeroDivisionError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>SyntaxError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>OSError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>MemoryError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>StopIteration<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>Error<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>SystemError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>ValueError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>UnicodeError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>UnicodeEncodeError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>UnicodeDecodeError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>UnicodeTranslateError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>UnsupportedOperation<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>NameError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>AttributeError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>RuntimeError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>LookupError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>IndexError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>KeyError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>EOFError<br />
<span style="white-space: pre-wrap;">  </span>GeneratorExit<br />
<span style="white-space: pre-wrap;">  </span>KeyboardInterrupt<br />
<span style="white-space: pre-wrap;">  </span>SystemExit</td>
<td>Exception<br />
<span style="white-space: pre-wrap;">  </span>LogicException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>BadFunctionCallException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>BadMethodCallException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>DomainException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>InvalidArgumentException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>LengthException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>OutOfRangeException<br />
<span style="white-space: pre-wrap;">  </span>RuntimeException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>OutOfBoundsException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>OverflowException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>RangeException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>UnderflowException<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>UnexpectedValueException</td>
<td>Exception<br />
<span style="white-space: pre-wrap;">  </span>NoMemoryError<br />
<span style="white-space: pre-wrap;">  </span>ScriptError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>LoadError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>NotImplementedError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>SyntaxError<br />
<span style="white-space: pre-wrap;">  </span>SignalException<br />
<span style="white-space: pre-wrap;">  </span>StandardError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>ArgumentError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>IOError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>EOFError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>IndexError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>LocalJumpError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>NameError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>RangeError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>RegexpError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>RuntimeError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>SecurityError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>SocketError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>SystemCallError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>Errno::*<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>SystemStackError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>ThreadError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>TypeError<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>ZeroDivisionError<br />
<span style="white-space: pre-wrap;">  </span>SystemExit<br />
<span style="white-space: pre-wrap;">  </span>fatal</td>
</tr>
<tr>
<td><a name="raise-exc" id="raise-exc"></a><a href="scripting#raise-exc-note">raise exception</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>throw new Error("bad arg");</td>
<td>raise Exception('bad arg')</td>
<td>throw new Exception("bad arg");</td>
<td><span style="color: gray"># raises RuntimeError</span><br />
raise "bad arg"</td>
</tr>
<tr>
<td><a name="catch-all-handler" id="catch-all-handler"></a><a href="scripting#catch-all-handler-note">catch-all handler</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>try {<br />
<span style="white-space: pre-wrap;">  </span>risky();<br />
} catch (e) {<br />
<span style="white-space: pre-wrap;">  </span>console.log(<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>'risky failed: ' + e.message);<br />
}</td>
<td>try:<br />
<span style="white-space: pre-wrap;">  </span>risky()<br />
except:<br />
<span style="white-space: pre-wrap;">  </span>print('risky failed')</td>
<td>try {<br />
<span style="white-space: pre-wrap;">  </span>risky();<br />
} catch (Exception $e) {<br />
<span style="white-space: pre-wrap;">  </span>echo "risky failed: ",<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>$e-&gt;getMessage(), "\n";<br />
}</td>
<td><span style="color: gray"># catches StandardError</span><br />
begin<br />
<span style="white-space: pre-wrap;">  </span>risky<br />
rescue<br />
<span style="white-space: pre-wrap;">  </span>print "risky failed: "<br />
<span style="white-space: pre-wrap;">  </span>puts $!.message<br />
end</td>
</tr>
<tr>
<td><a name="re-raise-exc" id="re-raise-exc"></a><a href="scripting#re-raise-exc-note">re-raise exception</a></td>
<td>try {<br />
<span style="white-space: pre-wrap;">  </span>throw new Error("bam!");<br />
} catch (e) {<br />
<span style="white-space: pre-wrap;">  </span>console.log('re-raising<span style="white-space: pre-wrap;">...</span>');<br />
<span style="white-space: pre-wrap;">  </span>throw e;<br />
}</td>
<td>try:<br />
<span style="white-space: pre-wrap;">  </span>raise Exception('bam!')<br />
except:<br />
<span style="white-space: pre-wrap;">  </span>print('re-raising<span style="white-space: pre-wrap;">...</span>')<br />
<span style="white-space: pre-wrap;">  </span>raise</td>
<td></td>
<td>begin<br />
<span style="white-space: pre-wrap;">  </span>raise "bam!"<br />
rescue<br />
<span style="white-space: pre-wrap;">  </span>puts "re-raising…"<br />
<span style="white-space: pre-wrap;">  </span>raise<br />
end<br />
<br />
<span style="color: gray"># if rescue clause raises different exception,<br />
# original exception preserved at e.cause</span></td>
</tr>
<tr>
<td><a name="last-exc-global" id="last-exc-global"></a><a href="scripting#last-exc-global-note">global variable for last exception</a></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>last exception:</em> sys.exc_info()[1]</span></td>
<td><span style="color: gray"><em>none</em></span></td>
<td><span style="color: gray"><em>last exception:</em> $!</span><br />
<span style="color: gray"><em>backtrace array of exc.:</em> $@</span><br />
<span style="color: gray"><em>exit status of child:</em> $?</span></td>
</tr>
<tr>
<td><a name="def-exc" id="def-exc"></a><a href="scripting#def-exc-note">define exception</a></td>
<td>function Bam(msg) {<br />
<span style="white-space: pre-wrap;">  </span>this.message = msg;<br />
}<br />
<br />
Bam.prototype = new Error;</td>
<td>class Bam(Exception):<br />
<span style="white-space: pre-wrap;">  </span>def <span style="white-space: pre-wrap;">__init__</span>(self):<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>super(Bam, self).<span style="white-space: pre-wrap;">__init__</span>('bam!')</td>
<td>class Bam extends Exception<br />
{<br />
<span style="white-space: pre-wrap;">  </span>function <span style="white-space: pre-wrap;">__</span>construct()<br />
<span style="white-space: pre-wrap;">  </span>{<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>parent::<span style="white-space: pre-wrap;">__</span>construct("bam!");<br />
<span style="white-space: pre-wrap;">  </span>}<br />
}</td>
<td>class Bam &lt; Exception<br />
<span style="white-space: pre-wrap;">  </span>def initialize<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>super("bam!")<br />
<span style="white-space: pre-wrap;">  </span>end<br />
end</td>
</tr>
<tr>
<td><a name="handle-exc" id="handle-exc"></a><a href="scripting#handle-exc-note">handle exception</a></td>
<td>try {<br />
<span style="white-space: pre-wrap;">  </span>throw new Bam("bam!");<br />
} catch (e) {<br />
<span style="white-space: pre-wrap;">  </span>if (e instanceof Bam) {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>console.log(e.message);<br />
<span style="white-space: pre-wrap;">  </span>}<br />
<span style="white-space: pre-wrap;">  </span>else {<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>throw e;<br />
<span style="white-space: pre-wrap;">  </span>}<br />
}</td>
<td>try:<br />
<span style="white-space: pre-wrap;">  </span>raise Bam()<br />
except Bam as e:<br />
<span style="white-space: pre-wrap;">  </span>print(e)</td>
<td>try {<br />
<span style="white-space: pre-wrap;">  </span>throw new Bam;<br />
} catch (Bam $e) {<br />
<span style="white-space: pre-wrap;">  </span>echo $e-&gt;getMessage(), "\n";<br />
}</td>
<td>begin<br />
<span style="white-space: pre-wrap;">  </span>raise Bam.new<br />
rescue Bam =&gt; e<br />
<span style="white-space: pre-wrap;">  </span>puts e.message<br />
end</td>
</tr>
<tr>
<td><a name="finally-block" id="finally-block"></a><a href="scripting#finally-block-note">finally block</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td>acquireResource();<br />
try {<br />
<span style="white-space: pre-wrap;">  </span>risky();<br />
} finally {<br />
<span style="white-space: pre-wrap;">  </span>releaseResource();<br />
}</td>
<td>acquire_resource()<br />
try:<br />
<span style="white-space: pre-wrap;">  </span>risky()<br />
finally:<br />
<span style="white-space: pre-wrap;">  </span>release_resource()</td>
<td><span style="color: gray"><em>PHP 5.5:</em></span><br />
acquire_resource();<br />
try {<br />
<span style="white-space: pre-wrap;">  </span>risky();<br />
}<br />
finally {<br />
<span style="white-space: pre-wrap;">  </span>release_resource();<br />
}</td>
<td>acquire_resource<br />
begin<br />
<span style="white-space: pre-wrap;">  </span>risky<br />
ensure<br />
<span style="white-space: pre-wrap;">  </span>release_resource<br />
end</td>
</tr>
<tr>
<th colspan="5"><a name="threads" id="threads"></a><a href="scripting#threads-note">threads</a></th>
</tr>
<tr>
<th></th>
<th>node.js</th>
<th>python</th>
<th>php</th>
<th>ruby</th>
</tr>
<tr>
<td><a name="start-thread" id="start-thread"></a><a href="scripting#start-thread-note">start thread</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td></td>
<td>class sleep10(threading.Thread):<br />
<span style="white-space: pre-wrap;">  </span>def run(self):<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>time.sleep(10)<br />
<br />
thr = sleep10()<br />
thr.start()</td>
<td></td>
<td>thr = Thread.new { sleep 10 }</td>
</tr>
<tr>
<td><a name="wait-on-thread" id="wait-on-thread"></a><a href="scripting#wait-on-thread-note">wait on thread</a><br />
<span style="white-space: pre-wrap;"> </span></td>
<td></td>
<td>thr.join()</td>
<td></td>
<td>thr.join</td>
</tr>
<tr>
<td><a name="sleep" id="sleep"></a><a href="scripting#sleep-note">sleep</a></td>
<td></td>
<td>import time<br />
<br />
time.sleep(0.5)</td>
<td><span style="color: gray"># a float argument will be truncated<br />
# to an integer:</span><br />
sleep(1);</td>
<td>sleep(0.5)</td>
</tr>
<tr>
<td><a name="timeout" id="timeout"></a><a href="scripting#timeout-note">timeout</a></td>
<td></td>
<td>import signal, time<br />
<br />
class Timeout(Exception): pass<br />
<br />
def timeout_handler(signo, fm):<br />
<span style="white-space: pre-wrap;">  </span>raise Timeout()<br />
<br />
signal.signal(signal.SIGALRM,<br />
<span style="white-space: pre-wrap;">  </span>timeout_handler)<br />
<br />
try:<br />
<span style="white-space: pre-wrap;">  </span>signal.alarm(5)<br />
<span style="white-space: pre-wrap;">  </span>might_take_too_long()<br />
except Timeout:<br />
<span style="white-space: pre-wrap;">  </span>pass<br />
signal.alarm(0)</td>
<td><span style="color: gray"><em>use</em> set_time_limit <em>to limit execution time of the entire script; use</em> stream_set_timeout <em>to limit time spent reading from a stream opened with</em> fopen <em>or</em> fsockopen</span></td>
<td>require 'timeout'<br />
<br />
begin<br />
<span style="white-space: pre-wrap;">  </span>Timeout.timeout(5) do<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>might_take_too_long<br />
<span style="white-space: pre-wrap;">  </span>end<br />
rescue Timeout::Error<br />
end</td>
</tr>
<tr>
<th></th>
<th><span style="color: #efefef"><span style="white-space: pre-wrap;">_____________________________________________________</span></span></th>
<th><span style="color: #efefef"><span style="white-space: pre-wrap;">_____________________________________________________</span></span></th>
<th><span style="color: #efefef"><span style="white-space: pre-wrap;">_____________________________________________________</span></span></th>
<th><span style="color: #efefef"><span style="white-space: pre-wrap;">_____________________________________________________</span></span></th>
</tr>
</table>
<p><strong><a href="scripting2">sheet two</a>:</strong> <a href="scripting2#streams">streams</a> | <a href="scripting2#async">asynchronous events</a> | <a href="scripting2#file">files</a> | <a href="scripting2#directories">directories</a> | <a href="scripting2#processes-environment">processes and environment</a> | <a href="scripting2#option-parsing">option parsing</a> | <a href="scripting2#libraries-namespaces">libraries and namespaces</a> | <a href="scripting2#objects">objects</a> | <a href="scripting2#inheritance-polymorphism">inheritance and polymorphism</a> | <a href="scripting2#reflection">reflection</a> | <a href="scripting2#net-web">net and web</a> | <a href="scripting2#gui">gui</a> | <a href="scripting2#databases">databases</a> | <a href="scripting2#unit-tests">unit tests</a> | <a href="scripting2#logging-profiling">logging</a> | <a href="scripting2#debugging-profiling">debugging</a></p>
<p><a name="version-note" id="version-note"></a></p>
<h1 id="toc0"><span><a href="scripting#version">Version</a></span></h1>
<p><a name="version-used-note" id="version-used-note"></a></p>
<h2 id="toc1"><span><a href="scripting#version-used">version used</a></span></h2>
<p>The versions used for testing code in the reference sheet.</p>
<p><a name="version-note" id="version-note"></a></p>
<h2 id="toc2"><span><a href="scripting#version">show version</a></span></h2>
<p>How to get the version.</p>
<p><strong>php:</strong></p>
<p>The function <tt>phpversion()</tt> will return the version number as a string.</p>
<p><strong>python:</strong></p>
<p>The following function will return the version number as a string:</p>
<div class="code">
<pre>
<code>import platform

platform.python_version()</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>Also available in the global constant <tt>RUBY_VERSION</tt>.</p>
<p><a name="implicit-prologue-note" id="implicit-prologue-note"></a></p>
<h2 id="toc3"><span><a href="scripting#implicit-prologue">implicit prologue</a></span></h2>
<p>Code which examples in the sheet assume to have already been executed.</p>
<p><strong>javascript:</strong></p>
<p><tt>underscore.js</tt> adds some convenience functions as attributes of an object which is normally stored in the underscore <tt>_</tt> variable. E.g.:</p>
<div class="code">
<pre>
<code>_.map([1, 2, 3], function(n){ return n * n; });</code>
</pre></div>
<p><a href="http://cdnjs.com/libraries/underscore.js">cdnjs</a> hosts underscore.js and other JavaScript libraries for situations where it is inconvenient to have the webserver host the libraries.</p>
<p>When using <tt>underscore.js</tt> with the Node REPL, there is a conflict, since the Node REPL uses the underscore <tt>_</tt> variable to store the result of the last evaluation.</p>
<div class="code">
<pre>
<code>$ npm install underscore

$ node

&gt; var us = require('underscore'); _

&gt; us.keys({"one": 1, "two": 2});
[ 'one', 'two' ]</code>
</pre></div>
<p><strong>php:</strong></p>
<p>The <tt>mbstring</tt> package adds UTF-8 aware string functions with <tt>mb_</tt> prefixes.</p>
<p><strong>python:</strong></p>
<p>We assume that <tt>os</tt>, <tt>re</tt>, and <tt>sys</tt> are always imported.</p>
<p><a name="grammar-execution-note" id="grammar-execution-note"></a></p>
<h1 id="toc4"><span><a href="scripting#grammar-execution">Grammar and Execution</a></span></h1>
<p><a name="interpreter-note" id="interpreter-note"></a></p>
<h2 id="toc5"><span><a href="scripting#interpreter">interpreter</a></span></h2>
<p>The customary name of the interpreter and how to invoke it.</p>
<p><strong>php:</strong></p>
<p><tt>php -f</tt> will only execute portions of the source file within a &lt;?php <span style="color: gray"><em>php code</em></span> ?&gt; 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.</p>
<p>If short tags are enabled, then php code can also be placed inside &lt;? <span style="color: gray"><em>php code</em></span> ?&gt; and &lt;?= <span style="color: gray"><em>php code</em></span> ?&gt; tags.</p>
<p>&lt;?= <span style="color: gray"><em>php code</em></span> ?&gt; is identical to &lt;?php echo <span style="color: gray"><em>php code</em></span> ?&gt;.</p>
<p><a name="repl-note" id="repl-note"></a></p>
<h2 id="toc6"><span><a href="scripting#repl">repl</a></span></h2>
<p>The customary name of the repl.</p>
<p><strong>php:</strong></p>
<p>The <tt>php -a</tt> REPL does not save or display the result of an expression.</p>
<p><strong>python:</strong></p>
<p>The python repl saves the result of the last statement in <span style="white-space: pre-wrap;">_</span>.</p>
<p><strong>ruby:</strong></p>
<p><tt>irb</tt> saves the result of the last statement in <span style="white-space: pre-wrap;">_</span>.</p>
<p><a name="cmd-line-program-note" id="cmd-line-program-note"></a></p>
<h2 id="toc7"><span><a href="scripting#cmd-line-program">command line program</a></span></h2>
<p>How to pass the code to be executed to the interpreter as a command line argument.</p>
<p><a name="block-delimiters-note" id="block-delimiters-note"></a></p>
<h2 id="toc8"><span><a href="scripting#block-delimiters">block delimiters</a></span></h2>
<p>How blocks are delimited.</p>
<p><strong>python:</strong></p>
<p>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.</p>
<p>The python repl switches from a <tt><span style="white-space: pre-wrap;">&gt;&gt;&gt;</span></tt> prompt to a … prompt inside a block. A blank line terminates the block.</p>
<p>Colons are also used to separate keys from values in dictionary literals and in sequence slice notation.</p>
<p><strong>ruby:</strong></p>
<p>Curly brackets {} delimit blocks. A matched curly bracket pair can be replaced by the <tt>do</tt> and <tt>end</tt> keywords. By convention curly brackets are used for one line blocks.</p>
<p>The <tt>end</tt> keyword also terminates blocks started by <tt>def</tt>, <tt>class</tt>, or <tt>module</tt>.</p>
<p>Curly brackets are also used for hash literals, and the #{ } notation is used to interpolate expressions into strings.</p>
<p><a name="statement-separator-note" id="statement-separator-note"></a></p>
<h2 id="toc9"><span><a href="scripting#statement-separator">statement separator</a></span></h2>
<p>How the parser determines the end of a statement.</p>
<p><strong>php:</strong></p>
<p>Inside braces statements must be terminated by a semicolon. The following causes a parse error:</p>
<div class="code">
<pre>
<code>&lt;? if (true) { echo "true" } ?&gt;</code>
</pre></div>
<p>The last statement inside <tt>&lt;?= ?&gt;</tt> or <tt>&lt;? ?&gt;</tt> tags does not need to be semicolon terminated, however. The following code is legal:</p>
<div class="code">
<pre>
<code>&lt;?= $a = 1 ?&gt;
&lt;? echo $a ?&gt;</code>
</pre></div>
<p><strong>python:</strong></p>
<p>Newline does not terminate a statement when:</p>
<ul>
<li>inside parens</li>
<li>inside list [] or dictionary {} literals</li>
</ul>
<p>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: """.</p>
<p>A newline that would normally terminate a statement can be escaped with a backslash.</p>
<p><strong>ruby:</strong></p>
<p>Newline does not terminate a statement when:</p>
<ul>
<li>inside single quotes '', double quotes "", backticks ``, or parens ()</li>
<li>after an operator such as + or , that expects another argument</li>
</ul>
<p>Ruby permits newlines in array [] or hash literals, but only after a comma , or associator =&gt;. Putting a newline before the comma or associator results in a syntax error.</p>
<p>A newline that would normally terminate a statement can be escaped with a backslash.</p>
<p><a name="source-code-encoding-note" id="source-code-encoding-note"></a></p>
<h2 id="toc10"><span><a href="scripting#source-code-encoding">source code encoding</a></span></h2>
<p>How to identify the character encoding for a source code file.</p>
<p>Setting the source code encoding makes it possible to safely use non-ASCII characters in string literals and regular expression literals.</p>
<p><a name="eol-comment-note" id="eol-comment-note"></a></p>
<h2 id="toc11"><span><a href="scripting#eol-comment">end-of-line comment</a></span></h2>
<p>How to create a comment that ends at the next newline.</p>
<p><a name="multiple-line-comment-note" id="multiple-line-comment-note"></a></p>
<h2 id="toc12"><span><a href="scripting#multiple-line-comment">multiple line comment</a></span></h2>
<p>How to comment out multiple lines.</p>
<p><strong>python:</strong></p>
<p>The triple single quote ''' and triple double quote """ syntax is a syntax for string literals.</p>
<p><a name="var-expr-note" id="var-expr-note"></a></p>
<h1 id="toc13"><span><a href="scripting#var-expr">Variables and Expressions</a></span></h1>
<p><a name="local-var-note" id="local-var-note"></a></p>
<h2 id="toc14"><span><a href="scripting#local-var">local variable</a></span></h2>
<p>How to declare variables which are local to the scope defining region which immediately contain them.</p>
<p><strong>php:</strong></p>
<p>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 <em>NULL</em>.</p>
<p><strong>python:</strong></p>
<p>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.</p>
<p><strong>ruby:</strong></p>
<p>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.</p>
<p>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.<em>name</em>. However, outside of class and modules local variables hide functions because functions are private methods in the class <em>Object</em>. Assignment to <em>name</em> will create a local variable if one with that name does not exist, even if there is a method <em>name</em>.</p>
<p><a name="file-scope-var-note" id="file-scope-var-note"></a></p>
<h2 id="toc15"><span><a href="scripting#file-scope-var">file scope variable</a></span></h2>
<p>How to define a variable with scope bound by the source file.</p>
<p><a name="global-var-note" id="global-var-note"></a></p>
<h2 id="toc16"><span><a href="scripting#global-var">global variable</a></span></h2>
<p>How to declare and access a variable with global scope.</p>
<p><strong>php:</strong></p>
<p>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 <em>global</em> keyword. A function must use the <em>global</em> keyword to access the global variable.</p>
<p><strong>python:</strong></p>
<p>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 <em>global</em> keyword.</p>
<p><strong>ruby:</strong></p>
<p>A variable is global if it starts with a dollar sign: $.</p>
<p><a name="const-note" id="const-note"></a></p>
<h2 id="toc17"><span><a href="scripting#const">constant</a></span></h2>
<p>How to declare a constant.</p>
<p><strong>php:</strong></p>
<p>A constant can be declared inside a class:</p>
<div class="code">
<pre>
<code>class Math {
  const pi = 3.14;
}</code>
</pre></div>
<p>Refer to a class constant like this:</p>
<div class="code">
<pre>
<code>Math::pi</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>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.</p>
<p><a name="assignment-note" id="assignment-note"></a></p>
<h2 id="toc18"><span><a href="scripting#assignment">assignment</a></span></h2>
<p>How to assign a value to a variable.</p>
<p><strong>python:</strong></p>
<p>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.</p>
<p>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 (=) when an equality test (==) was intended. Assignments can nevertheless be chained to assign a value to multiple variables:</p>
<div class="code">
<pre>
<code>a = b = 3</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>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.</p>
<p><a name="parallel-assignment-note" id="parallel-assignment-note"></a></p>
<h2 id="toc19"><span><a href="scripting#parallel-assignment">parallel assignment</a></span></h2>
<p>How to assign values to variables in parallel.</p>
<p><strong>python:</strong></p>
<p>The r-value can be a list or tuple:</p>
<div class="code">
<pre>
<code>nums = [1, 2, 3]
a, b, c = nums
more_nums = (6, 7, 8)
d, e, f = more_nums</code>
</pre></div>
<p>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:</p>
<div class="code">
<pre>
<code>(a,[b,c]) = [1,(2,3)]</code>
</pre></div>
<p>This assignment will raise a <tt>TypeError</tt>:</p>
<div class="code">
<pre>
<code>(a,(b,c)) = ((1,2),3)</code>
</pre></div>
<p>In Python 3 the splat operator <tt>*</tt> can be used to collect the remaining right side elements in a list:</p>
<div class="code">
<pre>
<code>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</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>The r-value can be an array:</p>
<div class="code">
<pre>
<code>nums = [1, 2, 3]
a,b,c = nums</code>
</pre></div>
<p><a name="swap-note" id="swap-note"></a></p>
<h2 id="toc20"><span><a href="scripting#swap">swap</a></span></h2>
<p>How to swap the values held by two variables.</p>
<p><a name="compound-assignment-note" id="compound-assignment-note"></a></p>
<h2 id="toc21"><span><a href="scripting#compound-assignment">compound assignment</a></span></h2>
<p>Compound assignment operators mutate a variable, setting it to the value of an operation which takes the previous value of the variable as an argument.</p>
<p>If <tt>&lt;OP&gt;</tt> is a binary operator and the language has the compound assignment operator <tt>&lt;OP&gt;=</tt>, then the following are equivalent:</p>
<div class="code">
<pre>
<code>x &lt;OP&gt;= y
x = x &lt;OP&gt; y</code>
</pre></div>
<p>The compound assignment operators are displayed in this order:</p>
<p><em>First row:</em> arithmetic operator assignment: addition, subtraction, multiplication, (float) division, integer division, modulus, and exponentiation.<br />
<em>Second row:</em> string concatenation assignment and string replication assignment<br />
<em>Third row:</em> logical operator assignment: and, or, xor<br />
<em>Fourth row:</em> bit operator assignment: left shift, right shift, and, or, xor.</p>
<p><strong>python:</strong></p>
<p>Python compound assignment operators do not return a value and hence cannot be used in expressions.</p>
<p><a name="incr-decr-note" id="incr-decr-note"></a></p>
<h2 id="toc22"><span><a href="scripting#incr-decr">increment and decrement</a></span></h2>
<p>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.</p>
<p>Incrementing a value two or more times in an expression makes the order of evaluation significant:</p>
<div class="code">
<pre>
<code>x = 1;
foo(++x, ++x); // foo(2, 3) or foo(3, 2)?

x = 1;
y = ++x/++x;  // y = 2/3 or y = 3/2?</code>
</pre></div>
<p>Python avoids the problem by not having an in-expression increment or decrement.</p>
<p>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:</p>
<div class="code">
<pre>
<code>x = 1
y = (x += 1)/(x += 1)</code>
</pre></div>
<p><strong>php:</strong></p>
<p>The increment and decrement operators also work on strings. There are postfix versions of these operators which evaluate to the value before mutation:</p>
<div class="code">
<pre>
<code>$x = 1;
$x++;
$x--;</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>The Integer class defines <tt>succ</tt>, <tt>pred</tt>, and <tt>next</tt>, which is a synonym for <tt>succ</tt>.</p>
<p>The String class defines <tt>succ</tt>, <tt>succ!</tt>, <tt>next</tt>, and <tt>next!</tt>. <tt>succ!</tt> and <tt>next!</tt> mutate the string.</p>
<p><a name="null-note" id="null-note"></a></p>
<h2 id="toc23"><span><a href="scripting#null">null</a></span></h2>
<p>The null literal.</p>
<p><a name="null-test-note" id="null-test-note"></a></p>
<h2 id="toc24"><span><a href="scripting#null-test">null test</a></span></h2>
<p>How to test if a variable contains null.</p>
<p><strong>php:</strong></p>
<p><em>$v == NULL</em> does not imply that <em>$v</em> is <em>NULL</em>, since any comparison between <em>NULL</em> and a falsehood will return true. In particular, the following comparisons are true:</p>
<div class="code">
<pre>
<code>$v = NULL;
if ($v == NULL) { echo "true"; }

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

$v = '';
if ($v == NULL) { echo "sadly true"; }</code>
</pre></div>
<p><a name="undef-var-note" id="undef-var-note"></a></p>
<h2 id="toc25"><span><a href="scripting#undef-var">undefined variable</a></span></h2>
<p>The result of attempting to access an undefined variable.</p>
<p><strong>python:</strong></p>
<p>Because a class can implement an <tt><span style="text-decoration: underline;">eq</span></tt> method to change the implementation of <tt>v == None</tt>, the expression can be <tt>True</tt> when <tt>v</tt> is not <tt>None</tt>.</p>
<p><strong>php:</strong></p>
<p>PHP does not provide the programmer with a mechanism to distinguish an undefined variable from a variable which has been set to NULL.</p>
<p><a href="https://gist.github.com/1157508">A test</a> showing that <tt>isset</tt> is the logical negation of <tt>is_null</tt>.</p>
<p><strong>python:</strong></p>
<p>How to test if a variable is defined:</p>
<div class="code">
<pre>
<code>not_defined = False
try: v
except NameError:
  not_defined = True</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>How to test if a variable is defined:</p>
<div class="code">
<pre>
<code>! defined?(v)</code>
</pre></div>
<p><a name="conditional-expr-note" id="conditional-expr-note"></a></p>
<h2 id="toc26"><span><a href="scripting#conditional-expr">conditional expression</a></span></h2>
<p>How to write a conditional expression. A ternary operator is an operator which takes three arguments. Since</p>
<p><span style="color: gray"><em>condition</em></span> ? <span style="color: gray"><em>true value</em></span> : <span style="color: gray"><em>false value</em></span></p>
<p>is the only ternary operator in C, it is unambiguous to refer to it as <em>the</em> ternary operator.</p>
<p><strong>python:</strong></p>
<p>The Python conditional expression comes from Algol.</p>
<p><strong>ruby:</strong></p>
<p>The Ruby <tt>if</tt> statement is also an expression:</p>
<div class="code">
<pre>
<code>x = if x &gt; 0
  x
else
  -x
end</code>
</pre></div>
<p><a name="arithmetic-logic-note" id="arithmetic-logic-note"></a></p>
<h1 id="toc27"><span><a href="scripting#arithmetic-logic">Arithmetic and Logic</a></span></h1>
<p><a name="true-false-note" id="true-false-note"></a></p>
<h2 id="toc28"><span><a href="scripting#true-false">true and false</a></span></h2>
<p>Literals for the booleans.</p>
<p>These are the return values of the relational operators.</p>
<p><strong>php:</strong></p>
<p>Any identifier which matches TRUE case-insensitive can be used for the TRUE boolean. Similarly for FALSE.</p>
<p>In general, PHP variable names are case-sensitive, but function names are case-insensitive.</p>
<p>When converted to a string for display purposes, TRUE renders as "1" and FALSE as "". The equality tests <tt>TRUE == 1</tt> and <tt>FALSE == ""</tt> evaluate as TRUE but the equality tests <tt>TRUE === 1</tt> and <tt>FALSE === ""</tt> evaluate as FALSE.</p>
<p><a name="falsehoods-note" id="falsehoods-note"></a></p>
<h2 id="toc29"><span><a href="scripting#falsehoods">falsehoods</a></span></h2>
<p>Values which behave like the false boolean in a conditional context.</p>
<p>Examples of conditional contexts are the conditional clause of an <tt>if</tt> statement and the test of a <tt>while</tt> loop.</p>
<p><strong>python:</strong></p>
<p>Whether a object evaluates to True or False in a boolean context can be customized by implementing a <span style="white-space: pre-wrap;">__nonzero__</span> (Python 2) or <span style="white-space: pre-wrap;">__bool__</span> (Python 3) instance method for the class.</p>
<p><a name="logical-op-note" id="logical-op-note"></a></p>
<h2 id="toc30"><span><a href="scripting#logical-op">logical operators</a></span></h2>
<p>Logical and, or, and not.</p>
<p><strong>php, ruby:</strong></p>
<p>&amp;&amp; and <span style="white-space: pre-wrap;">||</span> have higher precedence than assignment, compound assignment, and the ternary operator (?:), which have higher precedence than <em>and</em> and <em>or</em>.</p>
<p><a name="relational-op-note" id="relational-op-note"></a></p>
<h2 id="toc31"><span><a href="scripting#relational-op">relational operators</a></span></h2>
<p>Equality, inequality, greater than, less than, greater than or equal, less than or equal.</p>
<p><strong>php:</strong></p>
<p>Most of the relational 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.</p>
<p><strong>python:</strong></p>
<p>Relational operators can be chained. The following expressions evaluate to true:</p>
<div class="code">
<pre>
<code>1 &lt; 2 &lt; 3
1 == 1 != 2</code>
</pre></div>
<p>In general if <em>A<sub>i</sub></em> are expressions and <em>op<sub>i</sub></em> are relational operators, then</p>
<p><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><tt>A<sub>1</sub> op<sub>1</sub> A<sub>2</sub> op<sub>2</sub> A<sub>3</sub> … A<sub>n</sub> op<sub>n</sub> A<sub>n+1</sub></tt></p>
<p>is true if and only if each of the following is true</p>
<p><span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><tt>A<sub>1</sub> op<sub>1</sub> A<sub>2</sub></tt><br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><tt>A<sub>2</sub> op<sub>2</sub> A<sub>3</sub></tt><br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span>…<br />
<span style="white-space: pre-wrap;">  </span><span style="white-space: pre-wrap;">  </span><tt>A<sub>n</sub> op<sub>n</sub> A<sub>n+1</sub></tt></p>
<p><a name="min-max-note" id="min-max-note"></a></p>
<h2 id="toc32"><span><a href="scripting#min-max">min and max</a></span></h2>
<p>How to get the min and max.</p>
<p><a name="arith-op-note" id="arith-op-note"></a></p>
<h2 id="toc33"><span><a href="scripting#arith-op">arithmetic operators</a></span></h2>
<p>The operators for addition, subtraction, multiplication, float division, integer division, modulus, and exponentiation.</p>
<p><a name="int-div-note" id="int-div-note"></a></p>
<h2 id="toc34"><span><a href="scripting#int-div">integer division</a></span></h2>
<p>How to get the integer quotient of two integers.</p>
<p><a name="divmod-note" id="divmod-note"></a></p>
<h2 id="toc35"><span><a href="scripting#divmod">divmod</a></span></h2>
<p>How to get the quotient and remainder with single function call.</p>
<p><a name="int-div-zero-note" id="int-div-zero-note"></a></p>
<h2 id="toc36"><span><a href="scripting#int-div-zero">integer division by zero</a></span></h2>
<p>What happens when an integer is divided by zero.</p>
<p><a name="float-div-note" id="float-div-note"></a></p>
<h2 id="toc37"><span><a href="scripting#float-div">float division</a></span></h2>
<p>How to perform floating point division, even if the operands might be integers.</p>
<p><a name="float-div-zero-note" id="float-div-zero-note"></a></p>
<h2 id="toc38"><span><a href="scripting#float-div-zero">float division by zero</a></span></h2>
<p>What happens when a float is divided by zero.</p>
<p><a name="power-note" id="power-note"></a></p>
<h2 id="toc39"><span><a href="scripting#power">power</a></span></h2>
<p>How to get the value of a number raised to a power.</p>
<p><a name="sqrt-note" id="sqrt-note"></a></p>
<h2 id="toc40"><span><a href="scripting#sqrt">sqrt</a></span></h2>
<p>The square root function.</p>
<p><a name="sqrt-negative-one-note" id="sqrt-negative-one-note"></a></p>
<h2 id="toc41"><span><a href="scripting#sqrt-negative-one">sqrt -1</a></span></h2>
<p>The result of taking the square root of negative one.</p>
<p><a name="transcendental-func-note" id="transcendental-func-note"></a></p>
<h2 id="toc42"><span><a href="scripting#transcendental-func">transcendental functions</a></span></h2>
<p>Some mathematical functions. Trigonometric functions are in radians unless otherwise noted. Logarithms are natural unless otherwise noted.</p>
<p><strong>python:</strong></p>
<p>Python also has <em>math.log10</em>. To compute the log of <em>x</em> for base <em>b</em>, use:</p>
<div class="code">
<pre>
<code>math.log(x)/math.log(b)</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>Ruby also has <em>Math.log2</em>, <em>Math.log10</em>. To compute the log of <em>x</em> for base <em>b</em>, use</p>
<div class="code">
<pre>
<code>Math.log(x)/Math.log(b)</code>
</pre></div>
<p><a name="transcendental-const-note" id="transcendental-const-note"></a></p>
<h2 id="toc43"><span><a href="scripting#transcendental-const">transcendental constants</a></span></h2>
<p>Constants for π and Euler's constant.</p>
<p><a name="float-truncation-note" id="float-truncation-note"></a></p>
<h2 id="toc44"><span><a href="scripting#float-truncation">float truncation</a></span></h2>
<p>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.</p>
<p><a name="abs-val-note" id="abs-val-note"></a></p>
<h2 id="toc45"><span><a href="scripting#abs-val">absolute value</a></span></h2>
<p>How to get the absolute value of a number.</p>
<p><a name="int-overflow-note" id="int-overflow-note"></a></p>
<h2 id="toc46"><span><a href="scripting#int-overflow">integer overflow</a></span></h2>
<p>What happens when the largest representable integer is exceeded.</p>
<p><a name="float-overflow-note" id="float-overflow-note"></a></p>
<h2 id="toc47"><span><a href="scripting#float-overflow">float overflow</a></span></h2>
<p>What happens when the largest representable float is exceeded.</p>
<p><a name="rational-note" id="rational-note"></a></p>
<h2 id="toc48"><span><a href="scripting#rational">rational numbers</a></span></h2>
<p>How to create rational numbers and get the numerator and denominator.</p>
<p><strong>ruby:</strong></p>
<p>Require the library <em>mathn</em> and integer division will yield rationals instead of truncated integers.</p>
<p><a name="complex-note" id="complex-note"></a></p>
<h2 id="toc49"><span><a href="scripting#complex">complex numbers</a></span></h2>
<p><strong>python:</strong></p>
<p>Most of the functions in <em>math</em> have analogues in <em>cmath</em> which will work correctly on complex numbers.</p>
<p><a name="random-note" id="random-note"></a></p>
<h2 id="toc50"><span><a href="scripting#random">random integer, uniform float, normal float</a></span></h2>
<p>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.</p>
<p><a name="random-seed-note" id="random-seed-note"></a></p>
<h2 id="toc51"><span><a href="scripting#random-seed">set random seed, get and restore seed</a></span></h2>
<p>How to set the random seed; how to get the current random seed and later restore it.</p>
<p>All the languages in the sheet set the seed automatically to a value that is difficult to predict. The Ruby MRI interpreter uses the current time and process ID, for example. As a result there is usually no need to set the seed.</p>
<p>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.</p>
<p>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.</p>
<p><a name="bit-op-note" id="bit-op-note"></a></p>
<h2 id="toc52"><span><a href="scripting#bit-op">bit operators</a></span></h2>
<p>The bit operators for left shift, right shift, and, inclusive or, exclusive or, and negation.</p>
<p><a name="binary-octal-hex-literals-note" id="binary-octal-hex-literals-note"></a></p>
<h2 id="toc53"><span><a href="scripting#binary-octal-hex-literals">binary, octal, and hex literals</a></span></h2>
<p>Binary, octal, and hex integer literals</p>
<p><a name="radix-note" id="radix-note"></a></p>
<h2 id="toc54"><span><a href="scripting#radix">radix</a></span></h2>
<p>How to convert integers to strings of digits of a given base. How to convert such strings into integers.</p>
<p><strong>python</strong></p>
<p>Python has the functions <tt>bin</tt>, <tt>oct</tt>, and <tt>hex</tt> which take an integer and return a string encoding the integer in base 2, 8, and 16.</p>
<div class="code">
<pre>
<code>bin(42)
oct(42)
hex(42)</code>
</pre></div>
<p><a name="strings-note" id="strings-note"></a></p>
<h1 id="toc55"><span><a href="scripting#strings">Strings</a></span></h1>
<p><a name="str-type-note" id="str-type-note"></a></p>
<h2 id="toc56"><span><a href="scripting#str-type">string type</a></span></h2>
<p>The type for a string of Unicode characters.</p>
<p><strong>php:</strong></p>
<p>PHP assumes all strings have single byte characters.</p>
<p><strong>python:</strong></p>
<p>In Python 2.7 the <tt>str</tt> type assumes single byte characters. A separate <tt>unicode</tt> type is available for working with Unicode strings.</p>
<p>In Python 3 the <tt>str</tt> type supports multibtye characters and the <tt>unicode</tt> type has been removed.</p>
<p>There is a mutable <tt>bytearray</tt> type and an immutable <tt>bytes</tt> type for working with sequences of bytes.</p>
<p><strong>ruby:</strong></p>
<p>The <tt>String</tt> type supports multibtye characters. All strings have an explicit <tt>Encoding</tt>.</p>
<p><a name="str-literal-note" id="str-literal-note"></a></p>
<h2 id="toc57"><span><a href="scripting#str-literal">string literal</a></span></h2>
<p>The syntax for string literals.</p>
<p><strong>python:</strong></p>
<p>String literals may have a <tt>u</tt> prefix</p>
<div class="code">
<pre>
<code>u'lorem ipsum'
u"lorem ipsum"
u'''lorem
ipsum'''
u"""lorem
ipsum"""</code>
</pre></div>
<p>In Python 3, these are identical to literals without the <tt>u</tt> prefix.</p>
<p>In Python 2, these create <tt>unicode</tt> strings instead of <tt>str</tt> strings. Since the Python 2 <tt>unicode</tt> type corresponds to the Python 3 <tt>str</tt> type, portable code will use the <tt>u</tt> prefix.</p>
<p><strong>ruby:</strong></p>
<p>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.</p>
<div class="code">
<pre>
<code>s1 = %q(lorem ipsum)
s2 = %Q(#{s1} dolor sit amet)</code>
</pre></div>
<p><a name="newline-in-str-literal-note" id="newline-in-str-literal-note"></a></p>
<h2 id="toc58"><span><a href="scripting#newline-in-str-literal">newline in literal</a></span></h2>
<p>Whether newlines are permitted in string literals.</p>
<p><strong>python:</strong></p>
<p>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.</p>
<p>Triple quote literals, which are string literals terminated by three single quotes or three double quotes, can contain newlines:</p>
<div class="code">
<pre>
<code>'''This is
two lines'''

"""This is also
two lines"""</code>
</pre></div>
<p><a name="str-literal-esc-note" id="str-literal-esc-note"></a></p>
<h2 id="toc59"><span><a href="scripting#str-literal-esc">literal escapes</a></span></h2>
<p>Backslash escape sequences for inserting special characters into string literals.</p>
<table class="wiki-content-table">
<tr>
<th colspan="3">unrecognized backslash escape sequence</th>
</tr>
<tr>
<th></th>
<th>double quote</th>
<th>single quote</th>
</tr>
<tr>
<td>JavaScript</td>
<td></td>
<td></td>
</tr>
<tr>
<td>PHP</td>
<td>preserve backslash</td>
<td>preserve backslash</td>
</tr>
<tr>
<td>Python</td>
<td>preserve backslash</td>
<td>preserve backslash</td>
</tr>
<tr>
<td>Ruby</td>
<td>drop backslash</td>
<td>preserve backslash</td>
</tr>
</table>
<p><strong>python:</strong></p>
<p>When string literals have an <tt>r</tt> or <tt>R</tt> 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 <tt>r</tt> or <tt>R</tt> prefix that ends in a backslash. The <tt>r</tt> and <tt>R</tt> prefixes can be used with single or double quotes:</p>
<div class="code">
<pre>
<code>r'C:\Documents and Settings\Admin'
r"C:\Windows\System32"</code>
</pre></div>
<p>The \u<span style="color: gray"><em>hhhh</em></span> escapes are also available inside Python 2 Unicode literals. Unicode literals have a <em>u</em> prefiix:</p>
<div class="code">
<pre>
<code>u'lambda: \u03bb'</code>
</pre></div>
<p>This syntax is also available in Python 3.3, but not Python 3.2. In Python 3.3 it creates a string of type <tt>str</tt> which has the same features as the <tt>unicode</tt> type of Python 2.7.</p>
<p><a name="here-doc-note" id="here-doc-note"></a></p>
<h2 id="toc60"><span><a href="scripting#here-doc">here document</a></span></h2>
<p>Here documents are strings terminated by a custom identifier. They perform variable substitution and honor the same backslash escapes as double quoted strings.</p>
<p><strong>python:</strong></p>
<p>Triple quotes honor the same backslash escape sequences as regular quotes, so triple quotes can otherwise be used like here documents:</p>
<div class="code">
<pre>
<code>s = '''here document
there computer
'''</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>Put the customer identifier in single quotes to prevent variable interpolation and backslash escape interpretation:</p>
<div class="code">
<pre>
<code>s = &lt;&lt;'EOF'
Ruby code uses #{var} type syntax
to interpolate variables into strings.
EOF</code>
</pre></div>
<p><a name="var-interpolation-note" id="var-interpolation-note"></a></p>
<h2 id="toc61"><span><a href="scripting#var-interpolation">variable interpolation</a></span></h2>
<p>How to interpolate variables into strings.</p>
<p><strong>python:</strong></p>
<p>The f'1 + 1 = {1 + 1}' and f"1 + 1 = {1 + 1}" literals, which support variable interpolation and expression interpolation, are new in Python 3.6.</p>
<p><tt>str.format</tt> will take named or positional parameters. When used with named parameters <tt>str.format</tt> can mimic the variable interpolation feature of the other languages.</p>
<p>A selection of variables in scope can be passed explicitly:</p>
<div class="code">
<pre>
<code>count = 3
item = 'ball'
print('{count} {item}s'.format(
  count=count,
  item=item))</code>
</pre></div>
<p>Python 3 has <tt>format_map</tt> which accepts a <tt>dict</tt> as an argument:</p>
<div class="code">
<pre>
<code>count = 3
item = 'ball'
print('{count} {item}s'.format_map(locals()))</code>
</pre></div>
<p><a name="expr-interpolation-note" id="expr-interpolation-note"></a></p>
<h2 id="toc62"><span><a href="scripting#expr-interpolation">expression interpolation</a></span></h2>
<p>How to interpolate the result of evaluating an expression into a string.</p>
<p><a name="format-str-note" id="format-str-note"></a></p>
<h2 id="toc63"><span><a href="scripting#format-str">format string</a></span></h2>
<p>How to create a string using a printf style format.</p>
<p><strong>python:</strong></p>
<p>The % operator will interpolate arguments into printf-style format strings.</p>
<p>The <tt>str.format</tt> with positional parameters provides an alternative format using curly braces {0}, {1}, … for replacement fields.</p>
<p>The curly braces are escaped by doubling:</p>
<div class="code">
<pre>
<code>'to insert parameter {0} into a format, use {{{0}}}'.format(3)</code>
</pre></div>
<p>If the replacement fields appear in sequential order and aren't repeated, the numbers can be omitted:</p>
<div class="code">
<pre>
<code>'lorem {} {} {}'.format('ipsum', 13, 3.7)</code>
</pre></div>
<p><a name="mutable-str-note" id="mutable-str-note"></a></p>
<h2 id="toc64"><span><a href="scripting#mutable-str">are strings mutable?</a></span></h2>
<p>Are strings mutable?</p>
<p><a name="copy-str-note" id="copy-str-note"></a></p>
<h2 id="toc65"><span><a href="scripting#copy-str">copy string</a></span></h2>
<p>How to copy a string such that changes to the original do not modify the copy.</p>
<p><a name="str-concat-note" id="str-concat-note"></a></p>
<h2 id="toc66"><span><a href="scripting#str-concat">concatenate</a></span></h2>
<p>The string concatenation operator.</p>
<p><a name="str-replicate-note" id="str-replicate-note"></a></p>
<h2 id="toc67"><span><a href="scripting#str-replicate">replicate</a></span></h2>
<p>The string replication operator.</p>
<p><a name="translate-case-note" id="translate-case-note"></a></p>
<h2 id="toc68"><span><a href="scripting#translate-case">translate case</a></span></h2>
<p>How to put a string into all caps or all lower case letters.</p>
<p><a name="capitalize-note" id="capitalize-note"></a></p>
<h2 id="toc69"><span><a href="scripting#capitalize">capitalize</a></span></h2>
<p>How to capitalize a string and the words in a string.</p>
<p>The examples lowercase non-initial letters.</p>
<p><strong>php:</strong></p>
<p>How to define a UTF-8 aware version of <tt>ucfirst</tt>. This version also puts the rest of the string in lowercase:</p>
<div class="code">
<pre>
<code>function mb_ucfirst($string, $encoding = "UTF-8")
{
    $strlen = mb_strlen($string, $encoding);
    $firstChar = mb_substr($string, 0, 1, $encoding);
    $then = mb_substr(mb_strtolower($string), 1, $strlen - 1, $encoding);
    return mb_strtoupper($firstChar, $encoding) . $then;
}</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>Rails monkey patches the <tt>String</tt> class with the <tt>titleize</tt> method for capitalizing the words in a string.</p>
<p><a name="trim-note" id="trim-note"></a></p>
<h2 id="toc70"><span><a href="scripting#trim">trim</a></span></h2>
<p>How to remove whitespace from the ends of a string.</p>
<p><a name="pad-note" id="pad-note"></a></p>
<h2 id="toc71"><span><a href="scripting#pad">pad</a></span></h2>
<p>How to pad the edge of a string with spaces so that it is a prescribed length.</p>
<p><a name="num-to-str-note" id="num-to-str-note"></a></p>
<h2 id="toc72"><span><a href="scripting#num-to-str">number to string</a></span></h2>
<p>How to convert numeric data to string data.</p>
<p><a name="fmt-float-note" id="fmt-float-note"></a></p>
<h2 id="toc73"><span><a href="scripting#fmt-float">format float</a></span></h2>
<p>How to control the number of digits in a float when converting it to a string.</p>
<p><strong>python:</strong></p>
<p>The number after the decimal controls the number of digits after the decimal:</p>
<div class="code">
<pre>
<code>&gt;&gt;&gt; '%.2f' % math.pi
'3.14'</code>
</pre></div>
<p>The number after the decimal controls the total number of digits:</p>
<div class="code">
<pre>
<code>&gt;&gt;&gt; '{:.3}'.format(math.pi)
'3.14'</code>
</pre></div>
<p><a name="str-to-num-note" id="str-to-num-note"></a></p>
<h2 id="toc74"><span><a href="scripting#str-to-num">string to number</a></span></h2>
<p>How to convert string data to numeric data.</p>
<p><strong>php:</strong></p>
<p>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.</p>
<p><strong>python:</strong></p>
<p>float and int raise an error if called on a string and any part of the string is not numeric.</p>
<p><strong>ruby:</strong></p>
<p>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.</p>
<p><a name="str-join-note" id="str-join-note"></a></p>
<h2 id="toc75"><span><a href="scripting#str-join">string join</a></span></h2>
<p>How to concatenate the elements of an array into a string with a separator.</p>
<p><a name="split-note" id="split-note"></a></p>
<h2 id="toc76"><span><a href="scripting#split">split</a></span></h2>
<p>How to split a string containing a separator into an array of substrings.</p>
<p>See also <a href="scripting#scan">scan</a>.</p>
<p><strong>python:</strong></p>
<p><tt>str.split()</tt> takes simple strings as delimiters; use <tt>re.split()</tt> to split on a regular expression:</p>
<div class="code">
<pre>
<code>re.split('\s+', 'do re mi fa')
re.split('\s+', 'do re mi fa', 1)</code>
</pre></div>
<p><a name="split-in-two-note" id="split-in-two-note"></a></p>
<h2 id="toc77"><span><a href="scripting#split-in-two">split in two</a></span></h2>
<p>How to split a string in two.</p>
<p><strong>javascript:</strong></p>
<p>A regular expression is probably the best method for splitting a string in two:</p>
<div class="code">
<pre>
<code>var m = /^([^ ]+) (.+)/.exec("do re mi");
var first = m[1];
var rest = m[2];</code>
</pre></div>
<p>This technique works when the delimiter is a fixed string:</p>
<div class="code">
<pre>
<code>var a = "do re mi".split(" ");
var first = a[0];
var rest = a.splice(1).join(" ");</code>
</pre></div>
<p><strong>python:</strong></p>
<p>Methods for splitting a string into three parts using the first or last occurrence of a substring:</p>
<div class="code">
<pre>
<code>'do re mi'.partition(' ')         # returns ('do', ' ', 're mi')
'do re mi'.rpartition(' ')        # returns ('do re', ' ', 'mi')</code>
</pre></div>
<p><a name="split-keep-delimiters-note" id="split-keep-delimiters-note"></a></p>
<h2 id="toc78"><span><a href="scripting#split-keep-delimiters">split and keep delimiters</a></span></h2>
<p>How to split a string with the delimiters preserved as separate elements.</p>
<p><a name="prefix-suffix-test-note" id="prefix-suffix-test-note"></a></p>
<h2 id="toc79"><span><a href="scripting#prefix-suffix-test">prefix and suffix test</a></span></h2>
<p>How to test whether a string begins or ends with a substring.</p>
<p><a name="str-len-note" id="str-len-note"></a></p>
<h2 id="toc80"><span><a href="scripting#str-len">length</a></span></h2>
<p>How to get the length in characters of a string.</p>
<p><a name="index-substr-note" id="index-substr-note"></a></p>
<h2 id="toc81"><span><a href="scripting#index-substr">index of substring</a></span></h2>
<p>How to find the index of the leftmost occurrence of a substring in a string; how to find the index of the rightmost occurrence.</p>
<p><a name="extract-substr-note" id="extract-substr-note"></a></p>
<h2 id="toc82"><span><a href="scripting#extract-substr">extract substring</a></span></h2>
<p>How to extract a substring from a string by index.</p>
<p><a name="bytes-type-note" id="bytes-type-note"></a></p>
<h2 id="toc83"><span><a href="scripting#bytes-type">byte array type</a></span></h2>
<p>The type for an array of bytes.</p>
<p><a name="bytes-to-str-note" id="bytes-to-str-note"></a></p>
<h2 id="toc84"><span><a href="scripting#bytes-to-str">byte array to string</a></span></h2>
<p>How to convert an array of bytes to a string of Unicode characters.</p>
<p><a name="str-to-bytes-note" id="str-to-bytes-note"></a></p>
<h2 id="toc85"><span><a href="scripting#str-to-bytes">string to byte array</a></span></h2>
<p>How to convert a string of Unicode characters to an array of bytes.</p>
<p><a name="lookup-char-note" id="lookup-char-note"></a></p>
<h2 id="toc86"><span><a href="scripting#lookup-char">character lookup</a></span></h2>
<p>How to look up the character in a string at an index.</p>
<p><a name="chr-ord-note" id="chr-ord-note"></a></p>
<h2 id="toc87"><span><a href="scripting#chr-ord">chr and ord</a></span></h2>
<p>Converting characters to ASCII codes and back.</p>
<p>The languages in this reference sheet do not have character literals, so characters are represented by strings of length one.</p>
<p><a name="str-to-char-array-note" id="str-to-char-array-note"></a></p>
<h2 id="toc88"><span><a href="scripting#str-to-char-array">to array of characters</a></span></h2>
<p>How to split a string into an array of single character strings.</p>
<p><a name="translate-char-note" id="translate-char-note"></a></p>
<h2 id="toc89"><span><a href="scripting#translate-char">translate characters</a></span></h2>
<p>How to apply a character mapping to a string.</p>
<p><strong>python:</strong></p>
<p>In Python 2, the string of lowercase letters is in <tt>string.lowercase</tt> instead of <tt>string.ascii_lowercase</tt>.</p>
<p>In Python 2, the <tt>maketrans</tt> function is in the module <tt>string</tt> instead of <tt>str</tt>.</p>
<p><a name="delete-char-note" id="delete-char-note"></a></p>
<h2 id="toc90"><span><a href="scripting#delete-char">delete characters</a></span></h2>
<p>How to remove all specified characters from a string; how to remove all but the specified characters from a string.</p>
<p><a name="squeeze-char-note" id="squeeze-char-note"></a></p>
<h2 id="toc91"><span><a href="scripting#squeeze-char">squeeze characters</a></span></h2>
<p>How to replace multiple adjacent occurrences of a character with a single occurrence.</p>
<p><a name="regexes-note" id="regexes-note"></a></p>
<h1 id="toc92"><span><a href="scripting#regexes">Regular Expressions</a></span></h1>
<ul>
<li><a href="http://php.net/manual/en/book.pcre.php">PHP PCRE Regexes</a></li>
<li>Python re library: <a href="http://docs.python.org/library/re.html">2.7</a>, <a href="http://docs.python.org/release/3.1.3/library/re.html">3.1</a></li>
<li><a href="http://www.ruby-doc.org/core/classes/Regexp.html">Ruby Regexp</a></li>
</ul>
<p>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.</p>
<p>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.</p>
<p>Any string that doesn't contain regex metacharacters is a regex which matches itself. The regex metacharacters are: <tt>[ ] . | ( ) * + ? { } ^ $ \</tt></p>
<p><strong>character classes: [ ] .</strong></p>
<p>A character class is a set of characters in brackets: <tt>[ ].</tt> When used in a regex it matches any character it contains.</p>
<p>Character classes have their own set of metacharacters: <tt>^ - \ ]</tt></p>
<p>The <tt>^</tt> is only special when it is 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 <tt>^</tt> refers to itself.</p>
<p>The hyphen is used to specify character ranges: e.g. <tt>0-9</tt> or <tt>A-Z</tt>. When the hyphen is first or last inside the brackets it matches itself.</p>
<p>The backslash can be used to escape the above characters or the terminal character class delimiter: <tt>]</tt>. It can be used in character class abbreviations or string backslash escapes.</p>
<p>The period <tt>.</tt> is a character class abbreviation which matches any character except for newline. In all languages the period can be made to match all characters. PHP uses the <tt>m</tt> modifier. Python uses the <tt>re.M</tt> flag. Ruby uses the <tt>s</tt> modifier.</p>
<p><a name="regex-char-class-abbrev" id="regex-char-class-abbrev"></a><br />
<strong>character class abbreviations:</strong></p>
<table class="wiki-content-table">
<tr>
<th>abbrev</th>
<th>name</th>
<th>character class</th>
</tr>
<tr>
<td>\d</td>
<td>digit</td>
<td>[0-9]</td>
</tr>
<tr>
<td>\D</td>
<td>nondigit</td>
<td>[^0-9]</td>
</tr>
<tr>
<td>\h</td>
<td><span style="color: gray"><em>PHP:</em></span> horizontal whitespace character<br />
<span style="color: gray"><em>Ruby:</em></span> hex digit</td>
<td><span style="color: gray"><em>PHP:</em></span> [ \t]<br />
<span style="color: gray"><em>Ruby:</em></span> [0-9a-fA-F]</td>
</tr>
<tr>
<td>\H</td>
<td><span style="color: gray"><em>PHP:</em></span> not a horizontal whitespace character<br />
<span style="color: gray"><em>Ruby:</em></span> not a hex digit</td>
<td><span style="color: gray"><em>PHP:</em></span> [^ \t]<br />
<span style="color: gray"><em>Ruby:</em></span> [^0-9a-fA-F]</td>
</tr>
<tr>
<td>\s</td>
<td>whitespace character</td>
<td>[ \t\r\n\f]</td>
</tr>
<tr>
<td>\S</td>
<td>non whitespace character</td>
<td>[^ \t\r\n\f]</td>
</tr>
<tr>
<td>\v</td>
<td>vertical whitespace character</td>
<td>[\r\n\f]</td>
</tr>
<tr>
<td>\V</td>
<td>not a vertical whitespace character</td>
<td>[^\r\n\f]</td>
</tr>
<tr>
<td>\w</td>
<td>word character</td>
<td>[A-Za-z0-9_]</td>
</tr>
<tr>
<td>\W</td>
<td>non word character</td>
<td>[^A-Za-z0-9_]</td>
</tr>
</table>
<p><strong>alternation and grouping: | ( )</strong></p>
<p>The vertical pipe | is used for alternation and parens () for grouping.</p>
<p>A vertical pipe takes as its arguments everything up to the next vertical pipe, enclosing paren, or end of string.</p>
<p>Parentheses control the scope of alternation and the quantifiers described below. They 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 them when a match is made. A parenthesized subexpression can be removed from the groups with this syntax: <tt>(?:<span style="color: gray"><em>expr</em></span>)</tt></p>
<p><strong>quantifiers: * + ? { }</strong></p>
<p>As an argument quantifiers take the preceding regular character, character class, or group. The argument can itself be quantified, so that <tt>^a{4}*$</tt> matches strings with the letter a in multiples of 4.</p>
<table class="wiki-content-table">
<tr>
<th>quantifier</th>
<th># of occurrences of argument matched</th>
</tr>
<tr>
<td><span style="white-space: pre-wrap;">*</span></td>
<td>zero or more, greedy</td>
</tr>
<tr>
<td>+</td>
<td>one or more, greedy</td>
</tr>
<tr>
<td>?</td>
<td>zero or one, greedy</td>
</tr>
<tr>
<td>{m,n}</td>
<td><em>m</em> to <em>n</em>, greedy</td>
</tr>
<tr>
<td>{n}</td>
<td>exactly <em>n</em></td>
</tr>
<tr>
<td>{m,}</td>
<td><em>m</em> or more, greedy</td>
</tr>
<tr>
<td>{,n}</td>
<td>zero to <em>n</em>, greedy</td>
</tr>
<tr>
<td>*?</td>
<td>zero or more, lazy</td>
</tr>
<tr>
<td>+?</td>
<td>one or more, lazy</td>
</tr>
<tr>
<td>{m,n}?</td>
<td><em>m</em> to <em>n</em>, lazy</td>
</tr>
<tr>
<td>{m,}?</td>
<td><em>m</em> or more, lazy</td>
</tr>
<tr>
<td>{,n}?</td>
<td>zero to <em>n</em>, lazy</td>
</tr>
</table>
<p>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.</p>
<p><strong>anchors: ^ $</strong></p>
<table class="wiki-content-table">
<tr>
<th>anchor</th>
<th>matches</th>
</tr>
<tr>
<td>^</td>
<td>beginning of a string. In Ruby or when <em>m</em> modifier is used also matches right side of a newline</td>
</tr>
<tr>
<td>$</td>
<td>end of a string. In Ruby or when <em>m</em> modifier is used also matches left side of a newline</td>
</tr>
<tr>
<td>\A</td>
<td>beginning of the string</td>
</tr>
<tr>
<td>\b</td>
<td>word boundary. In between a \w and a \W character or in between a \w character and the edge of the string</td>
</tr>
<tr>
<td>\B</td>
<td>not a word boundary. In between two \w characters or two \W characters</td>
</tr>
<tr>
<td>\z</td>
<td>end of the string</td>
</tr>
<tr>
<td>\Z</td>
<td>end of the string unless it is a newline, in which case it matches the left side of the terminal newline</td>
</tr>
</table>
<p><strong>escaping: \</strong></p>
<p>To match a metacharacter, put a backslash in front of it. To match a backslash use two backslashes.</p>
<p><strong>php:</strong></p>
<p>PHP 5.3 still supports the EREG engine, though the functions which use it are deprecated. These include the <tt>split</tt> function and functions which start with <tt>ereg</tt>. The preferred functions are <tt>preg_split</tt> and the other functions with a <tt>preg</tt> prefix.</p>
<p><a name="regex-literal-note" id="regex-literal-note"></a></p>
<h2 id="toc93"><span><a href="scripting#regex-literal">literal, custom delimited literal</a></span></h2>
<p>The literal for a regular expression; the literal for a regular expression with a custom delimiter.</p>
<p><strong>javascript:</strong></p>
<p>The constructor for a regular expression is:</p>
<div class="code">
<pre>
<code>var rx = RegExp("lorem|ipsum");</code>
</pre></div>
<p><strong>php:</strong></p>
<p>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.</p>
<p>Here are the signatures from the PHP manual for the preg functions used in this sheet:</p>
<div class="code">
<pre>
<code>array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )

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

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

int preg_match_all ( string $pattern , string $subject [, array &amp;$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )</code>
</pre></div>
<p><strong>python:</strong></p>
<p>Python does not have a regex literal, but the <tt>re.compile</tt> function can be used to create regex objects.</p>
<p>Compiling regexes can always be avoided:</p>
<div class="code">
<pre>
<code>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')</code>
</pre></div>
<p><a name="ascii-char-class-abbrev-note" id="ascii-char-class-abbrev-note"></a></p>
<h2 id="toc94"><span><a href="scripting#ascii-char-class-abbrev">ascii character class abbreviations</a></span></h2>
<p>The supported <a href="scripting#regex-char-class-abbrev">character class abbreviations</a>.</p>
<p>Note that <tt>\h</tt> refers to horizontal whitespace (i.e. a space or tab) in PHP and a hex digit in Ruby. Similarly <tt>\H</tt> refers to something that isn't horizontal whitespace in PHP and isn't a hex digit in Ruby.</p>
<p><a name="unicode-char-class-abbrev-note" id="unicode-char-class-abbrev-note"></a></p>
<h2 id="toc95"><span><a href="scripting#unicode-char-class-abbrev">unicode character class abbreviations</a></span></h2>
<p>The supported character class abbreviations for sets of Unicode characters.</p>
<p>Each Unicode character belongs to one of these major categories:</p>
<table class="wiki-content-table">
<tr>
<td>C</td>
<td>Other</td>
</tr>
<tr>
<td>L</td>
<td>Letter</td>
</tr>
<tr>
<td>M</td>
<td>Mark</td>
</tr>
<tr>
<td>N</td>
<td>Number</td>
</tr>
<tr>
<td>P</td>
<td>Punctuation</td>
</tr>
<tr>
<td>S</td>
<td>Symbol</td>
</tr>
<tr>
<td>Z</td>
<td>Separator</td>
</tr>
</table>
<p>Each major category is subdivided into multiple minor categories. Each minor category has a two letter code, where the first letter is the major category. For example, <tt>Nd</tt> is "Number, decimal digit".</p>
<p>Download <a href="http://www.unicode.org/Public/UNIDATA/UnicodeData.txt">UnicodeData.txt</a> to find out which major and minor category and character belongs to.</p>
<p><a name="regex-anchors-note" id="regex-anchors-note"></a></p>
<h2 id="toc96"><span><a href="scripting#regex-anchors">anchors</a></span></h2>
<p>The supported anchors.</p>
<p><a name="regex-test-note" id="regex-test-note"></a></p>
<h2 id="toc97"><span><a href="scripting#regex-test">match test</a></span></h2>
<p>How to test whether a string matches a regular expression.</p>
<p><strong>python:</strong></p>
<p>The <tt>re.match</tt> function returns true only if the regular expression matches the beginning of the string. <tt>re.search</tt> returns true if the regular expression matches any substring of the of string.</p>
<p><strong>ruby:</strong></p>
<p><tt>match</tt> is a method of both <tt>Regexp</tt> and <tt>String</tt> so can match with both</p>
<div class="code">
<pre>
<code>/1999/.match("1999")</code>
</pre></div>
<p>and</p>
<div class="code">
<pre>
<code>"1999".match(/1999/)</code>
</pre></div>
<p>When variables are involved it is safer to invoke the <tt>Regexp</tt> method because string variables are more likely to contain <tt>nil</tt>.</p>
<p><a name="case-insensitive-regex-note" id="case-insensitive-regex-note"></a></p>
<h2 id="toc98"><span><a href="scripting#case-insensitive-regex">case insensitive match test</a></span></h2>
<p>How to perform a case insensitive match test.</p>
<p><a name="regex-modifiers-note" id="regex-modifiers-note"></a></p>
<h2 id="toc99"><span><a href="scripting#regex-modifiers">modifiers</a></span></h2>
<p>Modifiers that can be used to adjust the behavior of a regular expression.</p>
<p>The lists are not comprehensive. For all languages except Ruby there are additional modifiers.</p>
<table class="wiki-content-table">
<tr>
<th>modifier</th>
<th>behavior</th>
</tr>
<tr>
<td>e</td>
<td><span style="color: gray"><em>PHP:</em></span> 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.</td>
</tr>
<tr>
<td>g</td>
<td><span style="color: gray"><em>JavaScript:</em></span> read all non-overlapping matches into an array.</td>
</tr>
<tr>
<td>i, re.I</td>
<td><span style="color: gray"><em>all:</em></span> ignores case. Upper case letters match lower case letters and vice versa.</td>
</tr>
<tr>
<td>m, re.M</td>
<td><span style="color: gray"><em>JavaScript, PHP, Python:</em></span> makes the ^ and $ match the right and left edge of newlines in addition to the beginning and end of the string.<br />
<span style="color: gray"><em>Ruby:</em></span> makes the period . match newline characters.</td>
</tr>
<tr>
<td>o</td>
<td><span style="color: gray"><em>Ruby:</em></span> performs variable interpolation #{ } only once per execution of the program.</td>
</tr>
<tr>
<td>s, re.S</td>
<td><span style="color: gray"><em>PHP, Python:</em></span> makes the period . match newline characters.</td>
</tr>
<tr>
<td>x, re.X</td>
<td><span style="color: gray"><em>all:</em></span> ignores whitespace (outside of [] character classes) and #-style comments in the regex.</td>
</tr>
</table>
<p><strong>python:</strong></p>
<p>Python modifiers are bit flags. To use more than one flag at the same time, join them with bit or: |</p>
<p>There are alternative identifiers for the modifiers:</p>
<table class="wiki-content-table">
<tr>
<td>re.A</td>
<td>re.ASCII</td>
</tr>
<tr>
<td>re.I</td>
<td>re.IGNORECASE</td>
</tr>
<tr>
<td>re.M</td>
<td>re.MULTILINE</td>
</tr>
<tr>
<td>re.S</td>
<td>re.DOTALL</td>
</tr>
<tr>
<td>re.X</td>
<td>re.VERBOSE</td>
</tr>
</table>
<p><a name="subst-note" id="subst-note"></a></p>
<h2 id="toc100"><span><a href="scripting#subst">substitution</a></span></h2>
<p>How to replace all occurrences of a matching pattern in a string with the provided substitution string.</p>
<p><strong>php:</strong></p>
<p>The number of occurrences replaced can be controlled with a 4th argument to <tt>preg_replace</tt>:</p>
<div class="code">
<pre>
<code>$s = "foo bar bar";
preg_replace('/bar/', "baz", $s, 1);</code>
</pre></div>
<p>If no 4th argument is provided, all occurrences are replaced.</p>
<p><strong>python:</strong></p>
<p>The 3rd argument to <tt>sub</tt> controls the number of occurrences which are replaced.</p>
<div class="code">
<pre>
<code>s = 'foo bar bar'
re.compile('bar').sub('baz', s, 1)</code>
</pre></div>
<p>If there is no 3rd argument, all occurrences are replaced.</p>
<p><strong>ruby:</strong></p>
<p>The <em>gsub</em> operator returns a copy of the string with the substitution made, if any. The <em>gsub!</em> performs the substitution on the original string and returns the modified string.</p>
<p>The <em>sub</em> and <em>sub!</em> operators only replace the first occurrence of the match pattern.</p>
<p><a name="match-prematch-postmatch-note" id="match-prematch-postmatch-note"></a></p>
<h2 id="toc101"><span><a href="scripting#match-prematch-postmatch">match, prematch, postmatch</a></span></h2>
<p>How to get the substring that matched the regular expression, as well as the part of the string before and after the matching substring.</p>
<p><strong>ruby:</strong></p>
<p>The special variables <tt>$&amp;</tt>, <tt>$<span style="white-space: pre-wrap;">`</span></tt>, and <tt>$'</tt> also contain the match, prematch, and postmatch.</p>
<p><a name="group-capture-note" id="group-capture-note"></a></p>
<h2 id="toc102"><span><a href="scripting#group-capture">group capture</a></span></h2>
<p>How to get the substrings which matched the parenthesized parts of a regular expression.</p>
<p><strong>ruby:</strong></p>
<p>Ruby has syntax for extracting a group from a match in a single expression. The following evaluates to "1999":</p>
<div class="code">
<pre>
<code>"1999-07-08"[/(\d{4})-(\d{2})-(\d{2})/, 1]</code>
</pre></div>
<p><a name="named-group-capture-note" id="named-group-capture-note"></a></p>
<h2 id="toc103"><span><a href="scripting#named-group-capture">named group capture</a></span></h2>
<p>How to get the substrings which matched the parenthesized parts of a regular expression and put them into a dictionary.</p>
<p>For reference, we call the <tt>(?P&lt;foo&gt;<span style="white-space: pre-wrap;">...</span>)</tt> notation <em>Python-style</em> and the <tt>(?&lt;foo&gt;<span style="white-space: pre-wrap;">...</span>)</tt> notation <em>Perl-style</em>.</p>
<p><strong>php:</strong></p>
<p>PHP originally supported Python-style named groups since that was the style that was added to the PCRE regex engine. Perl-style named groups were added to PHP 5.2.</p>
<p><strong>python:</strong></p>
<p>The Python interpreter was the first to support named groups.</p>
<p><a name="scan-note" id="scan-note"></a></p>
<h2 id="toc104"><span><a href="scripting#scan">scan</a></span></h2>
<p>How to return all non-overlapping substrings which match a regular expression as an array.</p>
<p><a name="backreference-note" id="backreference-note"></a></p>
<h2 id="toc105"><span><a href="scripting#backreference">backreference in match and substitution</a></span></h2>
<p>How to use backreferences in a regex; how to use backreferences in the replacement string of substitution.</p>
<p><a name="recursive-regex-note" id="recursive-regex-note"></a></p>
<h2 id="toc106"><span><a href="scripting#recursive-regex">recursive regex</a></span></h2>
<p>An examples of a recursive regex.</p>
<p>The example matches substrings containing balanced parens.</p>
<p><a name="dates-time-note" id="dates-time-note"></a></p>
<h1 id="toc107"><span><a href="scripting#dates-time">Date and Time</a></span></h1>
<p>In ISO 8601 terminology, a <em>date</em> specifies a day in the Gregorian calendar and a <em>time</em> does not contain date information; it merely specifies a time of day. A data type which combines both date and time information is convenient, but ISO 8601 doesn't provide a name for such an entity. PHP, Python, and C# use the compound noun <em>datetime</em> for combined date and time values and we adopt it here as a generic term.</p>
<p>An useful property of <a href="http://en.wikipedia.org/wiki/ISO_8601">ISO 8601 dates, times, and datetimes</a> 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, zero-padded fields with numerical values for each term in the string representation.</p>
<p>The C standard library provides two methods for representing dates. The first is the <em>Unix epoch</em>, which is the seconds since the beginning of 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 Unix epoch is an example of a <em>serial datetime</em>, in which the value is stored as a single numeric value representing the difference in time in some unit from a specially designated datetime called the epoch.</p>
<p>Another serial datetime is the <em>Windows file time</em>, which is the number of 100 nanosecond intervals since the beginning of January 1, 1601 UTC. It was introduced when journaling was added to NTFS as part of the Windows 2000 launch.</p>
<p>Some serial datetimes use days as the unit. The Excel <em>serial number</em> is the number of days since December 31, 1899. The <em>Julian day number</em>, used in astronomy, is the number of days since November 24, 4714 BCE in the proleptic Gregorian calendar. Julian days start at noon GMT.</p>
<p>A <em>broken-down datetime</em> uses multiple numeric values to represent the components of a calendar date and time. An example from the C standard library is the <tt>tm</tt> struct, a definition of which can be found on Unix systems in <tt>/usr/include/time.h</tt>:</p>
<div class="code">
<pre>
<code>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 */
};</code>
</pre></div>
<p>The Linux man pages call the <tt>tm</tt> struct a "broken-down" date and time, whereas the BSD man pages call it a "broken-out" date and time.</p>
<p>The first day in the Gregorian calendar was 15 October 1582. The <em>proleptic Gregorian calendar</em> is an extension of the Gregorian calendar to earlier dates. When such dates are used, they should be called out to be precise. The epoch in the proleptic Gregorian calendar is the year 0001, also written 1 AD or 1 CE. The previous year is the year 0000, also written 1 BC or 1 BCE. The year before that is the year -0001, also written 2 BC or 2 BCE. The ISO 8601 standard recommends that years before 0000 or after 9999 be written with a plus or minus sign prefix.</p>
<p>An <em>ordinal date</em> is a broken-down date consisting of a year, followed by the day of the year. The ISO 8601 standard recommends that it be written in <tt>YYYY-DDD</tt> or <tt>YYYYDDD</tt> format. The corresponding <tt>strftime</tt> formats are <tt>%Y-%j</tt> and <tt>%Y%j</tt>.</p>
<p>A <em>week date</em> is a type of calendar which uses the year, week of the year, and day of the week to refer to to dates. In the ISO 8601 week date, the first week of the year is the week starting from Monday which contains January 4th. An ISO 8601 week date can thus have a different year number than the corresponding Gregorian date. The first week of the year is numbered <tt>01</tt>, and the first day of the week, Monday, is numbered <tt>1</tt>. Weeks are written in <tt>YYYY-Www-D</tt> or <tt>YYYYWwwD</tt> format, where the upper case W is literal. The corresponding <tt>strftime</tt> literals are <tt>%G-W%V-%u</tt> and <tt>%GW%V%u</tt>.</p>
<p>Common years have 365 days and leap years have 366 days. The extra day in February 29th. Leap years are years divisible by 4 but not 100, or years divisible by 400.</p>
<p>In 1967, the definition of a second was changed from 1/86,400 of a solar day to a value expressed in terms of radiation produced by <sup>133</sup>Cs. Because the length of a solar day is irregular, leap seconds are occasionally used to keep things in sync. This is accomplished by occasionally adding a leap second to the end of June 30th or December 31st. The system also allows for removing the last second of June 30th or December 31st, though as of 2014 this hasn't been done.</p>
<p><a name="broken-down-datetime-type-note" id="broken-down-datetime-type-note"></a></p>
<h2 id="toc108"><span><a href="scripting#broken-down-datetime-type">broken-down datetime type</a></span></h2>
<p>The data type used to hold a combined date and time.</p>
<p><strong>python:</strong></p>
<p>Python uses and exposes the <tt>tm</tt> struct of the C standard library. Python has a module called <tt>time</tt> which is a thin wrapper to the standard library functions which operate on this struct. Here is how get a <tt>tm</tt> struct in Python:</p>
<div class="code">
<pre>
<code>import time

utc = time.gmtime(time.time())
t = time.localtime(time.time())</code>
</pre></div>
<p><a name="current-datetime-note" id="current-datetime-note"></a></p>
<h2 id="toc109"><span><a href="scripting#current-datetime">current datetime</a></span></h2>
<p>How to get the combined date and time for the present moment in both local time and UTC.</p>
<p><a name="current-unix-epoch-note" id="current-unix-epoch-note"></a></p>
<h2 id="toc110"><span><a href="scripting#current-unix-epoch">current unix epoch</a></span></h2>
<p>How to get the current time as a Unix epoch timestamp.</p>
<p><a name="broken-down-datetime-to-unix-epoch-note" id="broken-down-datetime-to-unix-epoch-note"></a></p>
<h2 id="toc111"><span><a href="scripting#broken-down-datetime-to-unix-epoch">broken-down datetime to unix epoch</a></span></h2>
<p>How to convert a datetime type to the Unix epoch which is the number of seconds since the start of January 1, 1970 UTC.</p>
<p><strong>python:</strong></p>
<p>The Python datetime object created by <tt>now()</tt> and <tt>utcnow()</tt> has no timezone information associated with it. The <tt>strftime()</tt> method assumes a receiver with no time zone information represents a local time. Thus it is an error to call <tt>strftime()</tt> on the return value of <tt>utcnow()</tt>.</p>
<p>Here are two different ways to get the current Unix epoch. The second way is faster:</p>
<div class="code">
<pre>
<code>import calendar
import datetime

int(datetime.datetime.now().strftime('%s'))
calendar.timegm(datetime.datetime.utcnow().utctimetuple())</code>
</pre></div>
<p>Replacing <tt>now()</tt> with <tt>utcnow()</tt> in the first way, or <tt>utcnow()</tt> with <tt>now()</tt> in the second way produces an incorrect value.</p>
<p><a name="unix-epoch-to-broken-down-datetime-note" id="unix-epoch-to-broken-down-datetime-note"></a></p>
<h2 id="toc112"><span><a href="scripting#unix-epoch-to-broken-down-datetime">unix epoch to broken-down datetime</a></span></h2>
<p>How to convert the Unix epoch to a broken-down datetime.</p>
<p><a name="fmt-datetime-note" id="fmt-datetime-note"></a></p>
<h2 id="toc113"><span><a href="scripting#fmt-datetime">format datetime</a></span></h2>
<p>How to format a datetime as a string using using a string of format specifiers.</p>
<p>The format specifiers used by the <tt>strftime</tt> function from the standard C library and the Unix <tt>date</tt> command:</p>
<table class="wiki-content-table">
<tr>
<th></th>
<th>numeric</th>
<th>alphanumeric</th>
<th>notes</th>
</tr>
<tr>
<td><strong>year</strong></td>
<td>%Y %C%y</td>
<td></td>
<td>%C and %y are the first two and last two digits of a 4 digit year</td>
</tr>
<tr>
<td><strong>month</strong></td>
<td>%m</td>
<td>%B %b %h</td>
<td>%m is zero padded in {01, …, 12}<br />
%h is blank padded in {1, …, 12}</td>
</tr>
<tr>
<td><strong>day of month</strong></td>
<td>%d %e</td>
<td></td>
<td>%d is zero padded in {01, …, 31}<br />
%e is blank padded in {1, …, 31}</td>
</tr>
<tr>
<td><strong>hour</strong></td>
<td>%H %k</td>
<td>%I%p %l%p</td>
<td>%H and %k are in zero and blank padded</td>
</tr>
<tr>
<td><strong>minute</strong></td>
<td>%M</td>
<td></td>
<td>%M is zero padded in the range {00, …, 59}</td>
</tr>
<tr>
<td><strong>second</strong></td>
<td>%S</td>
<td></td>
<td>%S is zero padded, due to leap seconds it is in the range {00, …, 60}</td>
</tr>
<tr>
<td><strong>day of year</strong></td>
<td>%j</td>
<td></td>
<td>%j is zero padded in the range {000, …, 366}</td>
</tr>
<tr>
<td><strong>week date year</strong></td>
<td>%G %g</td>
<td></td>
<td>the ISO 8601 week date year. Used with %V and %u.</td>
</tr>
<tr>
<td><strong>week of year</strong></td>
<td>%V %U %W</td>
<td></td>
<td>%V is the ISO 8601 week of year. In {01, 53}. Used with %G<br />
%U is the week number when Sunday starts the week. In {00, 53}. Used with %Y and %C%y.<br />
%W is the week number when Monday starts the week. In {00, 53}. Used with %Y and %C%y.</td>
</tr>
<tr>
<td><strong>day of week</strong></td>
<td>%u %w</td>
<td>%A %a</td>
<td>%u is in {{1, …, 7} starting at Monday<br />
%w is in {0, …, 6} starting at Sunday</td>
</tr>
<tr>
<td><strong>unix epoch</strong></td>
<td>%s</td>
<td></td>
<td></td>
</tr>
<tr>
<td><strong>date</strong></td>
<td>%D %F %x</td>
<td>%v</td>
<td>%D is %m/%d/%y<br />
%F is %Y-%m-%d<br />
%x locale dependent; same as %D in US</td>
</tr>
<tr>
<td><strong>time</strong></td>
<td>%T %R %X</td>
<td>%r</td>
<td>%T is %H:%M:%S<br />
%R is %H:%M<br />
%X is locale dependent; same as %T in US<br />
%r is %I:%M:%S %p</td>
</tr>
<tr>
<td><strong>date and time</strong></td>
<td></td>
<td>%c</td>
<td>locale dependent</td>
</tr>
<tr>
<td><strong>date, time, and tmz</strong></td>
<td></td>
<td>%+</td>
<td>locale dependent</td>
</tr>
<tr>
<td><strong>time zone name</strong></td>
<td></td>
<td>%Z</td>
<td>the ambiguous 3 letter abbrevation; e.g. "PST"</td>
</tr>
<tr>
<td><strong>time zone offset</strong></td>
<td>%z</td>
<td></td>
<td>"-0800" for Pacific Standard Time</td>
</tr>
<tr>
<td><strong>percent sign</strong></td>
<td></td>
<td>%%</td>
<td></td>
</tr>
<tr>
<td><strong>newline</strong></td>
<td></td>
<td>%n</td>
<td></td>
</tr>
<tr>
<td><strong>tab</strong></td>
<td></td>
<td>%t</td>
<td></td>
</tr>
</table>
<p><strong>php:</strong></p>
<p>PHP supports strftime but it also has its own time formatting system used by <tt>date</tt>, <tt>DateTime::format</tt>, and <tt>DateTime::createFromFormat</tt>. The letters used in the PHP time formatting system are <a href="http://www.php.net/manual/en/datetime.createfromformat.php">described here</a>.</p>
<p><a name="parse-datetime-note" id="parse-datetime-note"></a></p>
<h2 id="toc114"><span><a href="scripting#parse-datetime">parse datetime</a></span></h2>
<p>How to parse a datetime using the format notation of the <tt>strptime</tt> function from the standard C library.</p>
<p><a name="parse-datetime-without-fmt-note" id="parse-datetime-without-fmt-note"></a></p>
<h2 id="toc115"><span><a href="scripting#parse-datetime-without-fmt">parse datetime w/o format</a></span></h2>
<p>How to parse a date without providing a format string.</p>
<p><a name="date-parts-note" id="date-parts-note"></a></p>
<h2 id="toc116"><span><a href="scripting#date-parts">date parts</a></span></h2>
<p>How to get the year, month, and day of month from a datetime.</p>
<p><a name="time-parts-note" id="time-parts-note"></a></p>
<h2 id="toc117"><span><a href="scripting#time-parts">time parts</a></span></h2>
<p>How to the hour, minute, and second from a datetime.</p>
<p><a name="build-datetime-note" id="build-datetime-note"></a></p>
<h2 id="toc118"><span><a href="scripting#build-datetime">build broken-down datetime</a></span></h2>
<p>How to build a broken-down datetime from the date parts and the time parts.</p>
<p><a name="datetime-subtraction-note" id="datetime-subtraction-note"></a></p>
<h2 id="toc119"><span><a href="scripting#datetime-subtraction">datetime subtraction</a></span></h2>
<p>The data type that results when subtraction is performed on two combined date and time values.</p>
<p><a name="add-duration-note" id="add-duration-note"></a></p>
<h2 id="toc120"><span><a href="scripting#add-duration">add duration</a></span></h2>
<p>How to add a duration to a datetime.</p>
<p>A duration can easily be added to a datetime value when the value is a Unix epoch value.</p>
<p>ISO 8601 distinguishes between a time interval, which is defined by two datetime 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.</p>
<p>ISO 8601 defines <a href="http://en.wikipedia.org/wiki/ISO_8601#Durations">notation for durations</a>. 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.</p>
<p><a name="local-tmz-determination-note" id="local-tmz-determination-note"></a></p>
<h2 id="toc121"><span><a href="scripting#local-tmz-determination">local time zone determination</a></span></h2>
<p>Do datetime values include time zone information. When a datetime value for the local time is created, how the local time zone is determined.</p>
<p>On Unix systems processes determine the local time zone by inspecting the binary file <tt>/etc/localtime</tt>. To examine it from the command line use <tt>zdump</tt>:</p>
<div class="code">
<pre>
<code>$ zdump /etc/localtime
/etc/localtime  Tue Dec 30 10:03:27 2014 PST</code>
</pre></div>
<p>On Windows the time zone name is stored in the registry at <tt>HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\TimeZoneKeyName</tt>.</p>
<p><strong>php:</strong></p>
<p>The default time zone can also be set in the <tt>php.ini</tt> file.</p>
<div class="code">
<pre>
<code>date.timezone = "America/Los_Angeles"</code>
</pre></div>
<p>Here is the list of <a href="http://php.net/timezones">timezones supported by PHP</a>.</p>
<p><a name="nonlocal-tmz-note" id="nonlocal-tmz-note"></a></p>
<h2 id="toc122"><span><a href="scripting#nonlocal-tmz">nonlocal time zone</a></span></h2>
<p>How to convert a datetime to the equivalent datetime in an arbitrary time zone.</p>
<p><a name="tmz-info-note" id="tmz-info-note"></a></p>
<h2 id="toc123"><span><a href="scripting#tmz-info">time zone info</a></span></h2>
<p>How to get the name of the time zone and the offset in hours from UTC.</p>
<p>Timezones are often identified by <a href="http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations">three or four letter abbreviations</a>. Many of the abbreviations do not uniquely identify a time zone. Furthermore many of the time zones have been altered in the past. The <a href="http://en.wikipedia.org/wiki/Tz_database">Olson database</a> (aka Tz database) decomposes the world into zones in which the local clocks have all been set to the same time since 1970; it gives these zones unique names.</p>
<p><strong>ruby:</strong></p>
<p>The <tt>Time</tt> class has a <tt>zone</tt> method which returns the time zone abbreviation for the object. There is a <tt>tzinfo</tt> gem which can be used to create time zone 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.</p>
<p><a name="daylight-savings-test-note" id="daylight-savings-test-note"></a></p>
<h2 id="toc124"><span><a href="scripting#daylight-savings-test">daylight savings test</a></span></h2>
<p>Is a datetime in daylight savings time?</p>
<p><a name="microseconds-note" id="microseconds-note"></a></p>
<h2 id="toc125"><span><a href="scripting#microseconds">microseconds</a></span></h2>
<p>How to get the microseconds component of a combined date and time value. The SI abbreviations for milliseconds and microseconds are <tt>ms</tt> and <tt><span style="white-space: pre-wrap;">μ</span>s</tt>, respectively. The C standard library uses the letter <tt>u</tt> as an abbreviation for <tt>micro</tt>. Here is a struct defined in <tt>/usr/include/sys/time.h</tt>:</p>
<div class="code">
<pre>
<code>struct timeval {
  time_t       tv_sec;   /* seconds since Jan. 1, 1970 */
  suseconds_t  tv_usec;  /* and microseconds */
};</code>
</pre></div>
<p><a name="sleep-note" id="sleep-note"></a></p>
<h2 id="toc126"><span><a href="scripting#sleep">sleep</a></span></h2>
<p>How to put the process to sleep for a specified number of seconds. In Python and Ruby the default version of <tt>sleep</tt> supports a fractional number of seconds.</p>
<p><strong>php:</strong></p>
<p>PHP provides <tt>usleep</tt> which takes an argument in microseconds:</p>
<div class="code">
<pre>
<code>usleep(500000);</code>
</pre></div>
<p><a name="timeout-note" id="timeout-note"></a></p>
<h2 id="toc127"><span><a href="scripting#timeout">timeout</a></span></h2>
<p>How to cause a process to timeout if it takes too long.</p>
<p>Techniques relying on SIGALRM only work on Unix systems.</p>
<p><a name="arrays-note" id="arrays-note"></a></p>
<h1 id="toc128"><span><a href="scripting#arrays">Arrays</a></span></h1>
<p>What the languages call their basic container types:</p>
<table class="wiki-content-table">
<tr>
<th></th>
<th>javascript</th>
<th>php</th>
<th>python</th>
<th>ruby</th>
</tr>
<tr>
<td><a href="scripting#array-literal">array</a></td>
<td></td>
<td>array</td>
<td>list, tuple, sequence</td>
<td>Array, Enumerable</td>
</tr>
<tr>
<td><a href="scripting#dict-literal">dictionary</a></td>
<td></td>
<td>array</td>
<td>dict, mapping</td>
<td>Hash</td>
</tr>
</table>
<p><strong>javascript:</strong></p>
<p><strong>php:</strong></p>
<p>PHP uses the same data structure for arrays and dictionaries.</p>
<p><strong>python:</strong></p>
<p>Python has the mutable <em>list</em> and the immutable <em>tuple</em>. Both are <em>sequences</em>. To be a <em>sequence</em>, a class must implement <span style="white-space: pre-wrap;">__getitem__</span>, <span style="white-space: pre-wrap;">__setitem__</span>, <span style="white-space: pre-wrap;">__delitem__</span>, <span style="white-space: pre-wrap;">__len__</span>, <span style="white-space: pre-wrap;">__contains__</span>, <span style="white-space: pre-wrap;">__iter__</span>, <span style="white-space: pre-wrap;">__add__</span>, <span style="white-space: pre-wrap;">__mul__</span>, <span style="white-space: pre-wrap;">__radd__</span>, and <span style="white-space: pre-wrap;">__rmul__</span>.</p>
<p><strong>ruby:</strong></p>
<p>Ruby provides an <em>Array</em> datatype. If a class defines an <em>each</em> iterator and a comparison operator &lt;=&gt;, then it can mix in the <em>Enumerable</em> module.</p>
<p><a name="array-literal-note" id="array-literal-note"></a></p>
<h2 id="toc129"><span><a href="scripting#array-literal">literal</a></span></h2>
<p>Array literal syntax.</p>
<p><strong>ruby:</strong></p>
<p>The <tt>%w</tt> operator splits the following string on whitespace and creates an array of strings from the words. The character following the <tt>%w</tt> is the string delimiter. If the following character is (, [, or {, then the character which terminates the string must be ), ], or }.</p>
<p>The <tt>%W</tt> operator is like the <tt>%w</tt> operator, except that double-quote style <tt>#{ }</tt> expressions will be interpolated.</p>
<p><a name="quote-words-note" id="quote-words-note"></a></p>
<h2 id="toc130"><span><a href="scripting#quote-words">quote words</a></span></h2>
<p>The quote words operator, which is a literal for arrays of strings where each string contains a single word.</p>
<p><a name="array-size-note" id="array-size-note"></a></p>
<h2 id="toc131"><span><a href="scripting#array-size">size</a></span></h2>
<p>How to get the number of elements in an array.</p>
<p><a name="array-empty-note" id="array-empty-note"></a></p>
<h2 id="toc132"><span><a href="scripting#array-empty">empty test</a></span></h2>
<p>How to test whether an array is empty.</p>
<p><a name="array-lookup-note" id="array-lookup-note"></a></p>
<h2 id="toc133"><span><a href="scripting#array-lookup">lookup</a></span></h2>
<p>How to access a value in an array by index.</p>
<p><strong>python:</strong></p>
<p>A negative index refers to the <em>length - index</em> element.</p>
<div class="code">
<pre>
<code>&gt;&gt;&gt; a = [1, 2, 3]
&gt;&gt;&gt; a[-1]
3</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>A negative index refers to to the <em>length - index</em> element.</p>
<p><a name="array-update-note" id="array-update-note"></a></p>
<h2 id="toc134"><span><a href="scripting#array-update">update</a></span></h2>
<p>How to update the value at an index.</p>
<p><a name="array-out-of-bounds-note" id="array-out-of-bounds-note"></a></p>
<h2 id="toc135"><span><a href="scripting#array-out-of-bounds">out-of-bounds behavior</a></span></h2>
<p>What happens when the value at an out-of-bounds index is referenced.</p>
<p><a name="array-element-index-note" id="array-element-index-note"></a></p>
<h2 id="toc136"><span><a href="scripting#array-element-index">element index</a></span></h2>
<p>How to get the index of an element in an array.</p>
<p><strong>php:</strong></p>
<p>Setting the 3rd argument of <tt>array_search</tt> to true makes the search use <tt>===</tt> for an equality test. Otherwise the <tt>==</tt> test is performed, which makes use of implicit type conversions.</p>
<p><a name="array-slice-note" id="array-slice-note"></a></p>
<h2 id="toc137"><span><a href="scripting#array-slice">slice</a></span></h2>
<p>How to slice a subarray from an array by specifying a start index and an end index; how to slice a subarray from an array by specifying an offset index and a length index.</p>
<p><strong>python:</strong></p>
<p>Slices can leave the first or last index unspecified, in which case the first or last index of the sequence is used:</p>
<div class="code">
<pre>
<code>&gt;&gt;&gt; a=[1, 2, 3, 4, 5]
&gt;&gt;&gt; a[:3]
[1, 2, 3]</code>
</pre></div>
<p>Python has notation for taking every nth element:</p>
<div class="code">
<pre>
<code>&gt;&gt;&gt; a=[1, 2, 3, 4, 5]
&gt;&gt;&gt; a[::2] 
[1, 3, 5]</code>
</pre></div>
<p>The third argument in the colon-delimited slice argument can be negative, which reverses the order of the result:</p>
<div class="code">
<pre>
<code>&gt;&gt;&gt; a = [1, 2, 3, 4]
&gt;&gt;&gt; a[::-1]
[4, 3, 2, 1]</code>
</pre></div>
<p><a name="array-slice-to-end-note" id="array-slice-to-end-note"></a></p>
<h2 id="toc138"><span><a href="scripting#array-slice-to-end">slice to end</a></span></h2>
<p>How to slice to the end of an array.</p>
<p>The examples take all but the first element of the array.</p>
<p><a name="array-back-note" id="array-back-note"></a></p>
<h2 id="toc139"><span><a href="scripting#array-back">manipulate back</a></span></h2>
<p>How to add and remove elements from the back or high index end of an array.</p>
<p>These operations can be used to use the array as a stack.</p>
<p><a name="array-front-note" id="array-front-note"></a></p>
<h2 id="toc140"><span><a href="scripting#array-front">manipulate front</a></span></h2>
<p>How to add and remove elements from the front or low index end of an array.</p>
<p>These operations can be used to use the array as a stack. They can be used with the operations that manipulate the back of the array to use the array as a queue.</p>
<p><a name="array-concatenation-note" id="array-concatenation-note"></a></p>
<h2 id="toc141"><span><a href="scripting#array-concatenation">concatenate</a></span></h2>
<p>How to create an array by concatenating two arrays; how to modify an array by concatenating another array to the end of it.</p>
<p><a name="replicate-array-note" id="replicate-array-note"></a></p>
<h2 id="toc142"><span><a href="scripting#replicate-array">replicate</a></span></h2>
<p>How to create an array containing the same value replicated <em>n</em> times.</p>
<p><a name="array-copy-note" id="array-copy-note"></a></p>
<h2 id="toc143"><span><a href="scripting#array-copy">copy</a></span></h2>
<p>How to make an address copy, a shallow copy, and a deep copy of an array.</p>
<p>After an address copy is made, modifications to the copy also modify the original array.</p>
<p>After a shallow copy is made, the addition, removal, or replacement of elements in the copy does not modify of the original array. However, if elements in the copy are modified, those elements are also modified in the original array.</p>
<p>A deep copy is a recursive copy. The original array is copied and a deep copy is performed on all elements of the array. No change to the contents of the copy will modify the contents of the original array.</p>
<p><strong>python:</strong></p>
<p>The slice operator can be used to make a shallow copy:</p>
<div class="code">
<pre>
<code>a2 = a[:]</code>
</pre></div>
<p><tt>list(v)</tt> always returns a list, but <tt>v[:]</tt> returns a value of the same as <tt>v</tt>. The slice operator can be used in this manner on strings and tuples but there is little incentive to do so since both are immutable.</p>
<p><tt>copy.copy</tt> can be used to make a shallow copy on types that don't support the slice operator such as a dictionary. Like the slice operator <tt>copy.copy</tt> returns a value with the same type as the argument.</p>
<p><a name="array-as-func-arg-note" id="array-as-func-arg-note"></a></p>
<h2 id="toc144"><span><a href="scripting#array-as-func-arg">array as function argument</a></span></h2>
<p>How an array is passed to a function when provided as an argument.</p>
<p><a name="iterate-over-array-note" id="iterate-over-array-note"></a></p>
<h2 id="toc145"><span><a href="scripting#iterate-over-array">iterate over elements</a></span></h2>
<p>How to iterate over the elements of an array.</p>
<p><a name="indexed-array-iteration-note" id="indexed-array-iteration-note"></a></p>
<h2 id="toc146"><span><a href="scripting#indexed-array-iteration">iterate over indices and elements</a></span></h2>
<p>How to iterate over the element-index pairs.</p>
<p><a name="range-iteration-note" id="range-iteration-note"></a></p>
<h2 id="toc147"><span><a href="scripting#range-iteration">iterate over range</a></span></h2>
<p>Iterate over a range without instantiating it as a list.</p>
<p><a name="range-array-note" id="range-array-note"></a></p>
<h2 id="toc148"><span><a href="scripting#range-array">instantiate range as array</a></span></h2>
<p>How to convert a range to an array.</p>
<p>Python 3 ranges and Ruby ranges implement some of the functionality of arrays without allocating space to hold all the elements.</p>
<p><strong>python:</strong></p>
<p>In Python 2 <tt>range()</tt> returns a list.</p>
<p>In Python 3 <tt>range()</tt> returns an object which implements the immutable sequence API.</p>
<p><strong>ruby:</strong></p>
<p>The Range class includes the Enumerable module.</p>
<p><a name="array-reverse-note" id="array-reverse-note"></a></p>
<h2 id="toc149"><span><a href="scripting#array-reverse">reverse</a></span></h2>
<p>How to create a reversed copy of an array, and how to reverse an array in place.</p>
<p><strong>python:</strong></p>
<p><tt>reversed</tt> returns an iterator which can be used in a <tt>for/in</tt> construct:</p>
<div class="code">
<pre>
<code>print("counting down:")
for i in reversed([1, 2, 3]):
  print(i)</code>
</pre></div>
<p><tt>reversed</tt> can be used to create a reversed list:</p>
<div class="code">
<pre>
<code>a = list(reversed([1, 2, 3]))</code>
</pre></div>
<p><a name="array-sort-note" id="array-sort-note"></a></p>
<h2 id="toc150"><span><a href="scripting#array-sort">sort</a></span></h2>
<p>How to create a sorted copy of an array, and how to sort an array in place. Also, how to set the comparison function when sorting.</p>
<p><strong>php:</strong></p>
<p><tt>usort</tt> sorts an array in place and accepts a comparison function as a 2nd argument:</p>
<div class="code">
<pre>
<code>function cmp($x, $y) {
  $lx = strtolower($x);
  $ly = strtolower($y);
  if ( $lx &lt; $ly ) { return -1; }
  if ( $lx == $ly ) { return 0; }
  return 1;
}

$a = ["b", "A", "a", "B"];

usort($a, "cmp");</code>
</pre></div>
<p><strong>python:</strong></p>
<p>In Python 2 it is possible to specify a binary comparision function when calling <tt>sort</tt>:</p>
<div class="code">
<pre>
<code>a = [(1, 3), (2, 2), (3, 1)]

a.sort(cmp=lambda a, b: -1 if a[1] &lt; b[1] else 1)

# a now contains:
[(3, 1), (2, 2), (1, 3)]</code>
</pre></div>
<p>In Python 3 the <tt>cmp</tt> parameter was removed. One can achieve the same effect by defining <tt><span style="text-decoration: underline;">cmp</span></tt> method on the class of the list element.</p>
<p><a name="array-dedupe-note" id="array-dedupe-note"></a></p>
<h2 id="toc151"><span><a href="scripting#array-dedupe">dedupe</a></span></h2>
<p>How to remove extra occurrences of elements from an array.</p>
<p><strong>python:</strong></p>
<p>Python sets support the <tt>len</tt>, <tt>in</tt>, and <tt>for</tt> operators. It may be more efficient to work with the result of the set constructor directly rather than convert it back to a list.</p>
<p><a name="membership-note" id="membership-note"></a></p>
<h2 id="toc152"><span><a href="scripting#membership">membership</a></span></h2>
<p>How to test for membership in an array.</p>
<p><a name="intersection-note" id="intersection-note"></a></p>
<h2 id="toc153"><span><a href="scripting#intersection">intersection</a></span></h2>
<p>How to compute an intersection.</p>
<p><strong>python:</strong></p>
<p>Python has literal notation for sets:</p>
<div class="code">
<pre>
<code>{1, 2, 3}</code>
</pre></div>
<p>Use <tt>set</tt> and <tt>list</tt> to convert lists to sets and vice versa:</p>
<div class="code">
<pre>
<code>a = list({1, 2, 3})
ensemble = set([1, 2, 3])</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>The intersect operator <tt>&amp;</tt> always produces an array with no duplicates.</p>
<p><a name="union-note" id="union-note"></a></p>
<h2 id="toc154"><span><a href="scripting#union">union</a></span></h2>
<p><strong>ruby:</strong></p>
<p>The union operator <tt>|</tt> always produces an array with no duplicates.</p>
<p><a name="set-diff-note" id="set-diff-note"></a></p>
<h2 id="toc155"><span><a href="scripting#set-diff">relative complement, symmetric difference</a></span></h2>
<p>How to compute the relative complement of two arrays or sets; how to compute the symmetric difference.</p>
<p><strong>ruby:</strong></p>
<p>If an element is in the right argument, then it will not be in the return value even if it is contained in the left argument multiple times.</p>
<p><a name="map-note" id="map-note"></a></p>
<h2 id="toc156"><span><a href="scripting#map">map</a></span></h2>
<p>Create an array by applying a function to each element of a source array.</p>
<p><strong>ruby:</strong></p>
<p>The <tt>map!</tt> method applies the function to the elements of the array in place.</p>
<p><tt>collect</tt> and <tt>collect!</tt> are synonyms for <tt>map</tt> and <tt>map!</tt>.</p>
<p><a name="filter-note" id="filter-note"></a></p>
<h2 id="toc157"><span><a href="scripting#filter">filter</a></span></h2>
<p>Create an array containing the elements of a source array which match a predicate.</p>
<p><strong>ruby:</strong></p>
<p>The in place version is <tt>select!</tt>.</p>
<p><tt>reject</tt> returns the complement of <tt>select</tt>. <tt>reject!</tt> is the in place version.</p>
<p>The <tt>partition</tt> method returns two arrays:</p>
<div class="code">
<pre>
<code>a = [1, 2, 3]
lt2, ge2 = a.partition { |n| n &lt; 2 }</code>
</pre></div>
<p><a name="reduce-note" id="reduce-note"></a></p>
<h2 id="toc158"><span><a href="scripting#reduce">reduce</a></span></h2>
<p>Return the result of applying a binary operator to all the elements of the array.</p>
<p><strong>python:</strong></p>
<p><tt>reduce</tt> is not needed to sum a list of numbers:</p>
<div class="code">
<pre>
<code>sum([1, 2, 3])</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>The code for the reduction step can be provided by name. The name can be a symbol or a string:</p>
<div class="code">
<pre>
<code>[1, 2, 3].inject(:+)

[1, 2, 3].inject("+")

[1, 2, 3].inject(0, :+)

[1, 2, 3].inject(0, "+")</code>
</pre></div>
<p><a name="universal-existential-test-note" id="universal-existential-test-note"></a></p>
<h2 id="toc159"><span><a href="scripting#universal-existential-test">universal and existential tests</a></span></h2>
<p>How to test whether a condition holds for all members of an array; how to test whether a condition holds for at least one member of any array.</p>
<p>A universal test is always true for an empty array. An existential test is always false for an empty array.</p>
<p>A existential test can readily be implemented with a filter. A universal test can also be implemented with a filter, but it is more work: one must set the condition of the filter to the negation of the predicate and test whether the result is empty.</p>
<p><a name="shuffle-sample-note" id="shuffle-sample-note"></a></p>
<h2 id="toc160"><span><a href="scripting#shuffle-sample">shuffle and sample</a></span></h2>
<p>How to shuffle an array. How to extract a random sample from an array.</p>
<p><strong>php:</strong></p>
<p>The <tt>array_rand</tt> function returns a random sample of the indices of an array. The result can easily be converted to a random sample of array values:</p>
<div class="code">
<pre>
<code>$a = [1, 2, 3, 4];
$sample = [];
foreach (array_rand($a, 2) as $i) { array_push($sample, $a[$i]); }</code>
</pre></div>
<p><a name="flatten-note" id="flatten-note"></a></p>
<h2 id="toc161"><span><a href="scripting#flatten">flatten</a></span></h2>
<p>How to flatten nested arrays by one level or completely.</p>
<p>When nested arrays are flattened by one level, the depth of each element which is not in the top level array is reduced by one.</p>
<p>Flattening nested arrays completely leaves no nested arrays. This is equivalent to extracting the leaf nodes of a tree.</p>
<p><strong>php, python:</strong></p>
<p>To flatten by one level use reduce. Remember to handle the case where an element is not array.</p>
<p>To flatten completely write a recursive function.</p>
<p><a name="zip-note" id="zip-note"></a></p>
<h2 id="toc162"><span><a href="scripting#zip">zip</a></span></h2>
<p>How to interleave arrays. In the case of two arrays the result is an array of pairs or an associative list.</p>
<p><a name="dictionaries-note" id="dictionaries-note"></a></p>
<h1 id="toc163"><span><a href="scripting#dictionaries">Dictionaries</a></span></h1>
<p><a name="dict-literal-note" id="dict-literal-note"></a></p>
<h2 id="toc164"><span><a href="scripting#dict-literal">literal</a></span></h2>
<p>The syntax for a dictionary literal.</p>
<p><a name="dict-size-note" id="dict-size-note"></a></p>
<h2 id="toc165"><span><a href="scripting#dict-size">size</a></span></h2>
<p>How to get the number of dictionary keys in a dictionary.</p>
<p><a name="dict-lookup-note" id="dict-lookup-note"></a></p>
<h2 id="toc166"><span><a href="scripting#dict-lookup">lookup</a></span></h2>
<p>How to lookup a dictionary value using a dictionary key.</p>
<p><a name="dict-missing-key-note" id="dict-missing-key-note"></a></p>
<h2 id="toc167"><span><a href="scripting#dict-missing-key">missing key behavior</a></span></h2>
<p>What happens when a lookup is performed on a key that is not in a dictionary.</p>
<p><strong>python:</strong></p>
<p>Use <tt>dict.get()</tt> to avoid handling <tt>KeyError</tt> exceptions:</p>
<div class="code">
<pre>
<code>d = {}
d.get('lorem')      # returns None
d.get('lorem', '')  # returns ''</code>
</pre></div>
<p><a name="dict-key-check-note" id="dict-key-check-note"></a></p>
<h2 id="toc168"><span><a href="scripting#dict-key-check">is key present</a></span></h2>
<p>How to check for the presence of a key in a dictionary without raising an exception. Distinguishes from the case where the key is present but mapped to null or a value which evaluates to false.</p>
<p><a name="dict-delete-note" id="dict-delete-note"></a></p>
<h2 id="toc169"><span><a href="scripting#dict-delete">delete</a></span></h2>
<p>How to remove a key/value pair from a dictionary.</p>
<p><a name="dict-assoc-array-note" id="dict-assoc-array-note"></a></p>
<h2 id="toc170"><span><a href="scripting#dict-assoc-array">from array of pairs, from even length array</a></span></h2>
<p>How to create a dictionary from an array of pairs; how to create a dictionary from an even length array.</p>
<p><a name="dict-merge-note" id="dict-merge-note"></a></p>
<h2 id="toc171"><span><a href="scripting#dict-merge">merge</a></span></h2>
<p>How to merge the values of two dictionaries.</p>
<p>In the examples, if the dictionaries <tt>d1</tt> and <tt>d2</tt> share keys then the values from <tt>d2</tt> will be used in the merged dictionary.</p>
<p><a name="dict-invert-note" id="dict-invert-note"></a></p>
<h2 id="toc172"><span><a href="scripting#dict-invert">invert</a></span></h2>
<p>How to turn a dictionary into its inverse. If a key 'foo' is mapped to value 'bar' by a dictionary, then its inverse will map the key 'bar' to the value 'foo'. However, if multiple keys are mapped to the same value in the original dictionary, then some of the keys will be discarded in the inverse.</p>
<p><a name="dict-iter-note" id="dict-iter-note"></a></p>
<h2 id="toc173"><span><a href="scripting#dict-iter">iteration</a></span></h2>
<p>How to iterate through the key/value pairs in a dictionary.</p>
<p><strong>python:</strong></p>
<p>In Python 2.7 <tt>dict.items()</tt> returns a list of pairs and <tt>dict.iteritems()</tt> returns an iterator on the list of pairs.</p>
<p>In Python 3 <tt>dict.items()</tt> returns an iterator and <tt>dict.iteritems()</tt> has been removed.</p>
<p><a name="dict-key-val-note" id="dict-key-val-note"></a></p>
<h2 id="toc174"><span><a href="scripting#dict-key-val">keys and values as arrays</a></span></h2>
<p>How to convert the keys of a dictionary to an array; how to convert the values of a dictionary to an array.</p>
<p><strong>python:</strong></p>
<p>In Python 3 <tt>dict.keys()</tt> and <tt>dict.values()</tt> return read-only views into the dict. The following code illustrates the change in behavior:</p>
<div class="code">
<pre>
<code>d = {}
keys = d.keys()
d['foo'] = 'bar'

if 'foo' in keys:
  print('running Python 3')
else:
  print('running Python 2')</code>
</pre></div>
<p><a name="dict-sort-values-note" id="dict-sort-values-note"></a></p>
<h2 id="toc175"><span><a href="scripting#dict-sort-values">sort by values</a></span></h2>
<p>How to iterate through the key-value pairs in the order of the values.</p>
<p><a name="dict-default-val-note" id="dict-default-val-note"></a></p>
<h2 id="toc176"><span><a href="scripting#dict-default-val">default value, computed value</a></span></h2>
<p>How to create a dictionary with a default value for missing keys; how to compute and store the value on lookup.</p>
<p><strong>php:</strong></p>
<p>Extend <tt>ArrayObject</tt> to compute values on lookup:</p>
<div class="code">
<pre>
<code>class Factorial extends ArrayObject {

  public function offsetExists($i) {
    return true;
  }

  public function offsetGet($i) {
    if(!parent::offsetExists($i)) {
      if ( $i &lt; 2 ) {
        parent::offsetSet($i, 1);
      }
      else {
        $n = $this-&gt;offsetGet($i-1);
        parent::offsetSet($i, $i*$n);
      }
    }
    return parent::offsetGet($i);
  }
}

$factorial = new Factorial();</code>
</pre></div>
<p><a name="functions-note" id="functions-note"></a></p>
<h1 id="toc177"><span><a href="scripting#functions">Functions</a></span></h1>
<p>Python has both functions and methods. Ruby only has methods: functions defined at the top level are in fact methods on a special main object. Perl subroutines can be invoked with a function syntax or a method syntax.</p>
<p><a name="def-func-note" id="def-func-note"></a></p>
<h2 id="toc178"><span><a href="scripting#def-func">define</a></span></h2>
<p>How to define a function.</p>
<p><a name="invoke-func-note" id="invoke-func-note"></a></p>
<h2 id="toc179"><span><a href="scripting#invoke-func">invoke</a></span></h2>
<p>How to invoke a function.</p>
<p><strong>python:</strong></p>
<p>Parens are mandatory, even for functions which take no arguments. Omitting the parens returns the function or method as an object. Whitespace can occur between the function name and the following left paren.</p>
<p>In Python 3 print is a function instead of a keyword; parens are mandatory around the argument.</p>
<p><strong>ruby:</strong></p>
<p>Ruby parens are optional. Leaving out the parens results in ambiguity when function invocations are nested. The interpreter resolves the ambiguity by assigning as many arguments as possible to the innermost function invocation, regardless of its actual arity. It is mandatory that the left paren not be separated from the method name by whitespace.</p>
<p><a name="apply-func-note" id="apply-func-note"></a></p>
<h2 id="toc180"><span><a href="scripting#apply-func">apply function to array</a></span></h2>
<p>How to apply a function to an array.</p>
<p><strong>perl:</strong></p>
<p>Perl passes the elements of arrays as individual arguments. In the following invocation, the function <tt>foo()</tt> does not know which arguments came from which array. For that matter it does not know how many arrays were used in the invocation:</p>
<div class="code">
<pre>
<code>foo(@a, @b);</code>
</pre></div>
<p>If the elements must be kept in their respective arrays the arrays must be passed by reference:</p>
<div class="code">
<pre>
<code>sub foo {
  my @a = @{$_[0]};
  my @b = @{$_[1]};
}

foo(\@a, \@b);</code>
</pre></div>
<p>When hashes are used as arguments, each key and value becomes its own argument.</p>
<p><a name="missing-arg-note" id="missing-arg-note"></a></p>
<h2 id="toc181"><span><a href="scripting#missing-arg">missing argument behavior</a></span></h2>
<p>What happens when a function is invoked with too few arguments.</p>
<p><a name="extra-arg-note" id="extra-arg-note"></a></p>
<h2 id="toc182"><span><a href="scripting#extra-arg">extra argument behavior</a></span></h2>
<p>What happens when a function is invoked with too many arguments.</p>
<p><a name="default-arg-note" id="default-arg-note"></a></p>
<h2 id="toc183"><span><a href="scripting#default-arg">default argument</a></span></h2>
<p>How to declare a default value for an argument.</p>
<p><a name="variadic-func-note" id="variadic-func-note"></a></p>
<h2 id="toc184"><span><a href="scripting#variadic-func">variadic function</a></span></h2>
<p>How to write a function which accepts a variable number of argument.</p>
<p><strong>python:</strong></p>
<p>This function accepts one or more arguments. Invoking it without any arguments raises a <tt>TypeError</tt>:</p>
<div class="code">
<pre>
<code>def poker(dealer, *players):
  ...</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>This function accepts one or more arguments. Invoking it without any arguments raises an <tt>ArgumentError</tt>:</p>
<div class="code">
<pre>
<code>def poker(dealer, *players)
  ...
end</code>
</pre></div>
<p><a name="param-alias-note" id="param-alias-note"></a></p>
<h2 id="toc185"><span><a href="scripting#param-alias">parameter alias</a></span></h2>
<p>How to make a parameter an alias of a variable in the caller.</p>
<p><a name="named-param-note" id="named-param-note"></a></p>
<h2 id="toc186"><span><a href="scripting#named-param">named parameters</a></span></h2>
<p>How to write a function which uses named parameters and how to invoke it.</p>
<p><strong>python:</strong></p>
<p>The caller can use named parameter syntax at the point of invocation even if the function was defined using positional parameters.</p>
<p>The splat operator * collects the remaining arguments into a list. In a function invocation, the splat can be used to expand an array into separate arguments.</p>
<p>The double splat operator ** collects named parameters into a dictionary. In a function invocation, the double splat expands a dictionary into named parameters.</p>
<p>A double splat operator can be used to force the caller to use named parameter syntax. This method has the disadvantage that spelling errors in the parameter name are not caught:</p>
<div class="code">
<pre>
<code>def fequal(x, y, **kwargs):
  eps = opts.get('eps') or 0.01
  return abs(x - y) &lt; eps</code>
</pre></div>
<p>In Python 3 named parameters can be made mandatory:</p>
<div class="code">
<pre>
<code>def fequal(x, y, *, eps):
  return abs(x-y) &lt; eps

fequal(1.0, 1.001, eps=0.01)  # True

fequal(1.0, 1.001)                 # raises TypeError</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>In Ruby 2.1 named parameters can be made mandatory:</p>
<div class="code">
<pre>
<code>def fequals(x, y, eps:)
  (x - y).abs &lt; eps
end

# false:
fequals(1.0, 1.001, eps: 0.1**10)
# ArgumentError:
fequals(1.0, 1.001)</code>
</pre></div>
<p><a name="retval-note" id="retval-note"></a></p>
<h2 id="toc187"><span><a href="scripting#retval">return value</a></span></h2>
<p>How the return value of a function is determined.</p>
<p><a name="multiple-retval-note" id="multiple-retval-note"></a></p>
<h2 id="toc188"><span><a href="scripting#multiple-retval">multiple return values</a></span></h2>
<p>How to return multiple values from a function.</p>
<p><a name="anonymous-func-literal-note" id="anonymous-func-literal-note"></a></p>
<h2 id="toc189"><span><a href="scripting#anonymous-func-literal">anonymous function literal</a></span></h2>
<p>The syntax for an anonymous function literal; i.e. a lambda function.</p>
<p><strong>python:</strong></p>
<p>Python lambdas cannot contain newlines or semicolons, and thus are limited to a single statement or expression. Unlike named functions, the value of the last statement or expression is returned, and a <em>return</em> is not necessary or permitted. Lambdas are closures and can refer to local variables in scope, even if they are returned from that scope.</p>
<p>If a closure function is needed that contains more than one statement, use a nested function:</p>
<div class="code">
<pre>
<code>def make_nest(x):
    b = 37
    def nest(y):
        c = x*y
        c *= b
        return c
    return nest

n = make_nest(12*2)
print(n(23))</code>
</pre></div>
<p>Python closures are read only.</p>
<p>A nested function can be returned and hence be invoked outside of its containing function, but it is not visible by its name outside of its containing function.</p>
<p><strong>ruby:</strong></p>
<p>The following lambda and Proc object behave identically:</p>
<div class="code">
<pre>
<code>sqr = lambda { |x| x * x }

sqr = Proc.new {|x| x * x }</code>
</pre></div>
<p>With respect to control words, Proc objects behave like blocks and lambdas like functions. In particular, when the body of a Proc object contains a <tt>return</tt> or <tt>break</tt> statement, it acts like a <tt>return</tt> or <tt>break</tt> in the code which invoked the Proc object. A <tt>return</tt> in a lambda merely causes the lambda to exit, and a <tt>break</tt> inside a lambda must be inside an appropriate control structure contained with the lambda body.</p>
<p>Ruby are alternate syntax for defining lambdas and invoking them:</p>
<div class="code">
<pre>
<code>sqr = -&gt;(x) {x*x}

sqr.(2)</code>
</pre></div>
<p><a name="invoke-anonymous-func-note" id="invoke-anonymous-func-note"></a></p>
<h2 id="toc190"><span><a href="scripting#invoke-anonymous-func">invoke anonymous function</a></span></h2>
<p>The syntax for invoking an anonymous function.</p>
<p><a name="func-as-val-note" id="func-as-val-note"></a></p>
<h2 id="toc191"><span><a href="scripting#func-as-val">function as value</a></span></h2>
<p>How to store a function in a variable and pass it as an argument.</p>
<p><strong>php:</strong></p>
<p>If a variable containing a string is used like a function then PHP will look for a function with the name in the string and attempt to invoke it.</p>
<p><strong>python:</strong></p>
<p>Python function are stored in variables by default. As a result a function and a variable with the same name cannot share the same scope. This is also the reason parens are mandatory when invoking Python functions.</p>
<p><a name="private-state-func-note" id="private-state-func-note"></a></p>
<h2 id="toc192"><span><a href="scripting#private-state-func">function with private state</a></span></h2>
<p>How to create a function with private state which persists between function invocations.</p>
<p><strong>python:</strong></p>
<p>Here is a technique for creating private state which exploits the fact that the expression for a default value is evaluated only once:</p>
<div class="code">
<pre>
<code>def counter(_state=[0]):
  _state[0] += 1
  return _state[0]

print(counter())</code>
</pre></div>
<p><a name="closure-note" id="closure-note"></a></p>
<h2 id="toc193"><span><a href="scripting#closure">closure</a></span></h2>
<p>How to create a first class function with access to the local variables of the local scope in which it was created.</p>
<p><strong>python:</strong></p>
<p>Python 2 has limited closures: access to local variables in the containing scope is read only and the bodies of anonymous functions must consist of a single expression.</p>
<p>Python 3 permits write access to local variables outside the immediate scope when declared with <tt>nonlocal</tt>.</p>
<p><a name="generator-note" id="generator-note"></a></p>
<h2 id="toc194"><span><a href="scripting#generator">generator</a></span></h2>
<p>How to create a function which can yield a value back to its caller and suspend execution.</p>
<p><strong>python:</strong></p>
<p>A Python generator is a function which returns an iterator.</p>
<p>An iterator is an object with two methods: <tt><span style="text-decoration: underline;">iter</span>()</tt>, which returns the iterator itself, and <tt>next()</tt>, which returns the next item or raises a <tt>StopIteration</tt> exception.</p>
<p>Python sequences, of which lists are an example, define an <tt><span style="text-decoration: underline;">iter</span>()</tt> for returned an iterator which traverses the sequence.</p>
<p>Python iterators can be used in <em>for/in</em> statements and list comprehensions.</p>
<p>In the table below, <tt>p</tt> and <tt>q</tt> are variables for iterators.</p>
<table class="wiki-content-table">
<tr>
<th colspan="2">itertools</th>
</tr>
<tr>
<th>generator</th>
<th>description</th>
</tr>
<tr>
<td>count(start=0, step=1)</td>
<td>arithmetic sequence of integers</td>
</tr>
<tr>
<td>cyle(p)</td>
<td>cycle over <tt>p</tt> endlessly</td>
</tr>
<tr>
<td>repeat(v, [n])</td>
<td>return <tt>v</tt> <tt>n</tt> times, or endlessly</td>
</tr>
<tr>
<td>chain(p, q)</td>
<td><tt>p</tt> followed by <tt>q</tt></td>
</tr>
<tr>
<td>compress(p, q)</td>
<td><tt>p</tt> if <tt>q</tt></td>
</tr>
<tr>
<td>groupby(p, func)</td>
<td></td>
</tr>
<tr>
<td>ifilter(pred, p)</td>
<td><tt>p</tt> if <tt>pred(p)</tt></td>
</tr>
<tr>
<td>ifilterfalse(pred, p)</td>
<td><tt>p</tt> if not <tt>pred(p)</tt></td>
</tr>
<tr>
<td>islice(p, [start], stop, [step])</td>
<td></td>
</tr>
<tr>
<td>imap</td>
<td></td>
</tr>
<tr>
<td>starmap()</td>
<td></td>
</tr>
<tr>
<td>tee()</td>
<td></td>
</tr>
<tr>
<td>takewhile()</td>
<td></td>
</tr>
<tr>
<td>izip()</td>
<td></td>
</tr>
<tr>
<td>izip_longest()</td>
<td></td>
</tr>
<tr>
<td>product()</td>
<td></td>
</tr>
<tr>
<td>permutations()</td>
<td></td>
</tr>
<tr>
<td>combinations()</td>
<td></td>
</tr>
<tr>
<td>combinations_with_replacement()</td>
<td></td>
</tr>
</table>
<p><strong>ruby:</strong></p>
<p>Ruby generators are called fibers.</p>
<p><a name="decorator-note" id="decorator-note"></a></p>
<h2 id="toc195"><span><a href="scripting#decorator">decorator</a></span></h2>
<p>A decorator replaces an invocation of one function with another in a way that that is imperceptible to the client.</p>
<p>Normally a decorator will add a small amount of functionality to the original function which it invokes. A decorator can modify the arguments before passing them to the original function or modify the return value before returning it to the client. Or it can leave the arguments and return value unmodified but perform a side effect such as logging the call.</p>
<p><a name="invoke-op-like-func-note" id="invoke-op-like-func-note"></a></p>
<h2 id="toc196"><span><a href="scripting#invoke-op-like-func">invoke operator like function</a></span></h2>
<p>How to call an operator using the function invocation syntax.</p>
<p>This is useful when dealing with an API which accepts a function as an argument.</p>
<p><strong>python:</strong></p>
<p>The <tt>operator</tt> module provides functions which perform the same operations as the various operators. Using these functions is more efficient than wrapping the operators in lambdas.</p>
<p><strong>ruby:</strong></p>
<p>All operators can be invoked with method invocation syntax. The binary operator invocation syntax can be regarded as syntactic sugar.</p>
<p><a name="execution-control-note" id="execution-control-note"></a></p>
<h1 id="toc197"><span><a href="scripting#execution-control">Execution Control</a></span></h1>
<p><a name="if-note" id="if-note"></a></p>
<h2 id="toc198"><span><a href="scripting#if">if</a></span></h2>
<p>The conditional branch statement.</p>
<p><strong>php:</strong></p>
<p>PHP has the following alternate syntax for <tt>if</tt> statements:</p>
<div class="code">
<pre>
<code>if ($n == 0): 
  echo "no hits\n";
elseif ($n == 1):
  echo "one hit\n";
else:
  echo "$n hits\n";
endif;</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>If an <tt>if</tt> statement is the last statement executed in a function, the return value is the value of the branch that executed.</p>
<p>Ruby <tt>if</tt> statements are expressions. They can be used on the right hand side of assignments:</p>
<div class="code">
<pre>
<code>m = if n
  1
else
  0
end</code>
</pre></div>
<p><a name="switch-note" id="switch-note"></a></p>
<h2 id="toc199"><span><a href="scripting#switch">switch</a></span></h2>
<p>A statement which branches based on the value of an expression.</p>
<p><a name="while-note" id="while-note"></a></p>
<h2 id="toc200"><span><a href="scripting#while">while</a></span></h2>
<p>How to loop over a block while a condition is true.</p>
<p><strong>php:</strong></p>
<p>PHP provides a <tt>do-while</tt> loop. The body of such a loop is guaranteed to execute at least once.</p>
<div class="code">
<pre>
<code>$i = 0;
do {
    echo $i;
} while ($i &gt; 0);</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>Ruby provides a loop with no exit condition:</p>
<div class="code">
<pre>
<code>def yes(expletive="y")
  loop do
   puts expletive
  end
end</code>
</pre></div>
<p>Ruby also provides the <tt>until</tt> loop.</p>
<p>Ruby loops can be used in expression contexts but they always evaluate to <tt>nil</tt>.</p>
<p><a name="for-note" id="for-note"></a></p>
<h2 id="toc201"><span><a href="scripting#for">for</a></span></h2>
<p>How to write a C-style for loop.</p>
<p><a name="break-note" id="break-note"></a></p>
<h2 id="toc202"><span><a href="scripting#break">break</a></span></h2>
<p>A <tt>break</tt> statement exits a <tt>while</tt> or <tt>for</tt> loop immediately.</p>
<p><a name="continue-note" id="continue-note"></a></p>
<h2 id="toc203"><span><a href="scripting#continue">continue</a></span></h2>
<p>A <tt>continue</tt> statement skips ahead to the next iteration of a <tt>while</tt> or <tt>for</tt> loop.</p>
<p><strong>ruby:</strong></p>
<p>There is also a <tt>redo</tt> statement, which restarts the current iteration of a loop.</p>
<p><a name="statement-modifiers-note" id="statement-modifiers-note"></a></p>
<h2 id="toc204"><span><a href="scripting#statement-modifiers">statement modifiers</a></span></h2>
<p>Clauses added to the end of a statement to control execution.</p>
<p>Ruby has conditional statement modifiers. Ruby also has looping statement modifiers.</p>
<p><strong>ruby:</strong></p>
<p>Ruby has the looping statement modifiers <tt>while</tt> and <tt>until</tt>:</p>
<div class="code">
<pre>
<code>i = 0
i += 1 while i &lt; 10

j = 10
j -= 1 until j &lt; 0</code>
</pre></div>
<p><a name="exceptions-note" id="exceptions-note"></a></p>
<h1 id="toc205"><span><a href="scripting#exceptions">Exceptions</a></span></h1>
<p><a name="base-exc-note" id="base-exc-note"></a></p>
<h2 id="toc206"><span><a href="scripting#base-exc">base exception</a></span></h2>
<p>The base exception type or class that can be used to catch all exceptions.</p>
<p><a name="predefined-exc-note" id="predefined-exc-note"></a></p>
<h2 id="toc207"><span><a href="scripting#predefined-exc">predefined exceptions</a></span></h2>
<p>A list of the more commonly encountered exceptions.</p>
<p><strong>python:</strong></p>
<p>Code for inspecting the descendants of a base class:</p>
<div class="code">
<pre>
<code>def print_class_hierarchy(cls, indent=0):
    print(' ' * indent, cls.__name__)
    for subclass in cls.__subclasses__():
        print_class_hierarchy(subclass, indent + 2)</code>
</pre></div>
<p>The complete Python 3.5 exception hierarchy:</p>
<div class="code">
<pre>
<code>BaseException
  Exception
    TypeError
    ImportError
      ZipImportError
    AssertionError
    error
    ArithmeticError
      FloatingPointError
      OverflowError
      ZeroDivisionError
    SyntaxError
      IndentationError
        TabError
    OSError
      BlockingIOError
      TimeoutError
      PermissionError
      FileExistsError
      ConnectionError
        BrokenPipeError
        ConnectionAbortedError
        ConnectionResetError
        ConnectionRefusedError
      NotADirectoryError
      UnsupportedOperation
      ChildProcessError
      IsADirectoryError
      ItimerError
      InterruptedError
      FileNotFoundError
      ProcessLookupError
    BufferError
    ReferenceError
    MemoryError
    StopIteration
    StopAsyncIteration
    Error
    SystemError
      CodecRegistryError
    ValueError
      UnicodeError
        UnicodeEncodeError
        UnicodeDecodeError
        UnicodeTranslateError
      UnsupportedOperation
    NameError
      UnboundLocalError
    AttributeError
    Warning
      DeprecationWarning
      SyntaxWarning
      FutureWarning
      RuntimeWarning
      UserWarning
      UnicodeWarning
      BytesWarning
      PendingDeprecationWarning
      ResourceWarning
      ImportWarning
    RuntimeError
      RecursionError
      NotImplementedError
      _DeadlockError
    LookupError
      IndexError
      KeyError
      CodecRegistryError
    EOFError
  GeneratorExit
  KeyboardInterrupt
  SystemExit</code>
</pre></div>
<p><a name="raise-exc-note" id="raise-exc-note"></a></p>
<h2 id="toc208"><span><a href="scripting#raise-exc">raise exception</a></span></h2>
<p>How to raise exceptions.</p>
<p><strong>ruby:</strong></p>
<p>Ruby has a <em>throw</em> keyword in addition to <em>raise</em>. <em>throw</em> can have a symbol as an argument, and will not convert a string to a RuntimeError exception.</p>
<p><a name="catch-all-handler-note" id="catch-all-handler-note"></a></p>
<h2 id="toc209"><span><a href="scripting#catch-all-handler">catch-all handler</a></span></h2>
<p>How to catch exceptions.</p>
<p><strong>php:</strong></p>
<p>PHP code must specify a variable name for the caught exception. <em>Exception</em> is the top of the exception hierarchy and will catch all exceptions.</p>
<p>Internal PHP functions usually do not throw exceptions. They can be converted to exceptions with this signal handler:</p>
<div class="code">
<pre>
<code>function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");</code>
</pre></div>
<p><strong>ruby:</strong></p>
<p>A <em>rescue Exception</em> clause will catch any exception. A <em>rescue</em> clause with no exception type specified will catch exceptions that are subclasses of <em>StandardError</em>. Exceptions outside <em>StandardError</em> are usually unrecoverable and hence not handled in code.</p>
<p>In a <em>rescue</em> clause, the <em>retry</em> keyword will cause the <em>begin</em> clause to be re-executed.</p>
<p>In addition to <em>begin</em> and <em>rescue</em>, ruby has <em>catch</em>:</p>
<div class="code">
<pre>
<code>catch (:done) do
  loop do
    retval = work
    throw :done if retval &lt; 10
  end
end</code>
</pre></div>
<p><a name="re-raise-exc-note" id="re-raise-exc-note"></a></p>
<h2 id="toc210"><span><a href="scripting#re-raise-exc">re-raise exception</a></span></h2>
<p>How to re-raise an exception preserving the original stack trace.</p>
<p><strong>python:</strong></p>
<p>If the exception is assigned to a variable in the <tt>except</tt> clause and the variable is used as the argument to <tt>raise</tt>, then a new stack trace is created.</p>
<p><strong>ruby:</strong></p>
<p>If the exception is assigned to a variable in the <tt>rescue</tt> clause and the variable is used as the argument to <tt>raise</tt>, then the original stack trace is preserved.</p>
<p><a name="last-exc-global-note" id="last-exc-global-note"></a></p>
<h2 id="toc211"><span><a href="scripting#last-exc-global">global variable for last exception</a></span></h2>
<p>The global variable name for the last exception raised.</p>
<p><a name="def-exc-note" id="def-exc-note"></a></p>
<h2 id="toc212"><span><a href="scripting#def-exc">define exception</a></span></h2>
<p>How to define a new variable class.</p>
<p><a name="handle-exc-note" id="handle-exc-note"></a></p>
<h2 id="toc213"><span><a href="scripting#handle-exc">handle exception</a></span></h2>
<p>How to catch exceptions of a specific type and assign the exception a name.</p>
<p><strong>php:</strong></p>
<p>PHP exceptions when caught must always be assigned a variable name.</p>
<p><a name="finally-block-note" id="finally-block-note"></a></p>
<h2 id="toc214"><span><a href="scripting#finally-block">finally block</a></span></h2>
<p>A block of statements that is guaranteed to be executed even if an exception is thrown or caught.</p>
<p><a name="threads-note" id="threads-note"></a></p>
<h1 id="toc215"><span><a href="scripting#threads">Threads</a></span></h1>
<p><a name="start-thread-note" id="start-thread-note"></a></p>
<h2 id="toc216"><span><a href="scripting#start-thread">start thread</a></span></h2>
<p><strong>ruby:</strong></p>
<p>Ruby MRI threads are operating system threads, but a global interpreter lock prevents more than one thread from executing Ruby code at a time.</p>
<p><a name="wait-on-thread-note" id="wait-on-thread-note"></a></p>
<h2 id="toc217"><span><a href="scripting#wait-on-thread">wait on thread</a></span></h2>
<p>How to make a thread wait for another thread to finish.</p>

                    </div>
        </div>
      </div>
      <div id="license-area" class="license-area">
        <a href="https://github.com/clarkgrubb/hyperpolyglot/issues">issue tracker</a> |
        content of this page licensed under
        <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">
        creative commons attribution-sharealike 3.0</a>
        <br>
      </div>
    </div>
  </div>
</div>

<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-17129977-2']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

</body>
</html>