functions

スクリプト言語の比較

http://hyperpolyglot.org/scripting を参考に、スクリプト言語の勉強をしてまいります。

functions

































































  perl php python ruby
function declaration

sub add { $_[0] + $_[1] }

<?php
function add($a, $b) { return $a + $b; }
?>

def add(a,b): return a+b

def add(a,b); a+b; end

function invocation

add(1,2);

<?php
add(3,7);
?>

add(1,2)

add(1,2)

missing argument

set to undef


set to NULL with warning


raises TypeError


raises ArgumentError
default value

none

<?php
function my_log($x, $b=10) {
?>

def log(x,base=10):

def log(x,base=10)

arbitrary number of arguments

@_ contains all values

<?php
function add() {
  return array_sum(func_get_args());
}
?>

def add(first,*rest):
  if not rest:
    return first
  else:
    return first+add(*rest)

def add(first, *rest)
  if rest.empty?
    first
  else
    first + add(*rest)
  end
end

named parameter definition

none


none

def f(**d):

def f(h)

named parameter invocation

none


none

f(eps=0.01)

f(:eps => 0.01)

pass number or string by reference

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

<?php
function foo(&$x, &$y) {
  $x += 1;
  $y .= 'ly';
}
$n = 7;
$s = 'hard';
foo($n, $s);
?>



not possible


not possible
pass array or hash by reference

sub foo {
  $_[0][2] = 5;
  $_[1]{'f'} = -1;
}
my @a = (1,2,3);
my %h = ('t'=> 1, 'f' => 0);
foo(\@a, \%h);

<?php
function foo(&$x, &$y) {
  $x[2] = 5;
  $y['f'] = -1;
}
$a = array(1,2,3);
$h = array('t'=>1,'f'=>0);
foo($a, $h);
?>

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

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

return value

return arg or
last expression evaluated


return arg or NULL


return arg or None


return arg or
last expression evaluated
multiple return values

sub first_and_second {
  return ($_[0], $_[1]);
}
@a = (1,2,3);
($x, $y) = first_and_second(@a);

<?php
function first_and_second(&$a) {
  return array($a[0], $a[1]);
}
$a = array(1,2,3);
list($x, $y) =
  first_and_second($a);
?>

def first_and_second(a):
  return a[0], a[1]
x, y = first_and_second([1,2,3])

def first_and_second(a)
  return a[0], a[1]
end
x, y = first_and_second([1,2,3])

lambda declaration

$f = sub { $_[0] * $_[0] }

<?php
$f = create_function('$x','return $x*$x;');
?>

f = lambda x: x * x

f = lambda { |x| x * x }

lambda invocation

$f->(2)

<?php
$f(2)
?>

f(2)

f.call(2)

function with private state

{
  my $i = 0;
  sub counter() { ++$i }
}
print counter() . "\n";

<?php
function counter() {
  static $i = 0;
  return ++$i;
}
echo counter();
?>

# state not private:
def counter():
  counter.i += 1
  return counter.i
counter.i = 0
print(counter())



none
closure

sub make_counter() {
  my $i = 0;
  return sub() { ++$i };
}
my $nays = make_counter();
print $nays->() . "\n"

<?php
function make_counter() {
  $i = 0;
  return function () use (&$i) {
    return ++$i;
  };
}
$nays = make_counter();
echo $nays();
?>

# python 3:
def make_counter():
  i = 0
  def counter():
    nonlocal i
    i += 1
    return i
  return counter
nays = make_counter()

def make_counter()
  i = 0
  return lambda { i +=1; i }
end
nays = make_counter
puts nays.call

generator

none


none

def make_counter():
  i = 0
  while True:
    i += 1
    yield(i)
nays = make_counter()
print(nays.next())

# ruby 1.9:
def make_counter()
  return Fiber.new do
    i = 0
    while true
      i += 1
      Fiber.yield i
    end
  end
end
nays = make_counter
puts nays.resume