Hack é uma linguagem para HHVM que interage perfeitamente com o PHP. O propósito é permitir o desenvolvimento ágil com a disciplina da tipagem estática.
Hack também fornece alguns recursos específicos:
- generics
- collections
- nullable
Daqui a pouco vou falar mais sobre esses recursos!
<?hh echo "Hi, I'm a Hack script!";
Type Annotations
Tradicionalmente, uma linguagen com tipagem dinâmica permite o desenvolvimento ágil, mas sacrifica a capacidade de detectar erros rapidamente. O Hack reconcilia o ciclo de desenvolvimento rápido do PHP com a disciplina fornecida pelo tipagem estática.
<?hh function hello(): void { echo "Type Annotations :)"; }
Hack também especifica o tipo de retorno no final da declaração de uma função/método, não no início, como acontece no C#.
<?hh function add_numbers(int $number1): int { return $number1; }
Outro detalhe importante: o PHP permite o uso de sinônimos para manipulação de tipos, mas o Hack eliminou isso. Na prática isso significa que:
- double, real não sâo permitidos para
float
. - boolean não é permitido para
bool
. - integer também não é permitido para
int
.
Generics
Um método genérico tem a mesma funcionalidade dos tipos genéricos: suportar tipos fortes, definidos e genéricos (d’oh).
Assim como nos tipos genéricos, os métodos genéricos existem para permitir a passagem de valores genéricos para um determinado método.
<?hh class Box<T> { protected T $data; public function __construct(T $data) { $this->data = $data; } public function getData(): T { return $this->data; } }
A classe Box tem um parâmetro de tipo genérico. Para qualquer instância de Box, T assume qualquer tipo disponível, e ainda podemos utilizar o mesmo tipo para o parâmetro de um método da mesma classe, no nosso caso, o método getData().
<?hh $main = new Box(9); echo $main->getData(); //Output '9'
Collections
Collections é uma das coisas mais úteis na maioria das linguagens, mas por alguma razão o PHP ainda não tem essa funcionalidade como algo padrão. Elas são grupos de objetos similarmente iguais que são agrupados. Elas são especializadas para armazenamento e recuperação de dados. Atualmente, Hack implementa os seguintes tipos de Collections:
- Vector: ordenada, baseada no índice;
- Map: dictionary-style ordenada;
- Set: armazena valores exclusivos;
- Pair: baseada em índice que pode conter exatamente dois elementos.
Exemplo usando Vector:
<?hh $vector = Vector {5, 10}; $vector->add(15); $vector->add(20); $vector[] = 25; $vector->removeKey(2); foreach ($vector as $item) { echo $item . "\n"; }
O exemplo acima retorna:
5 10 20 25
Agora um exemplo usando Map:
<?hh $map = Map {"A" => 1, "B" => 2, "C" => 3}; $map["D"] = 4; $map["E"] = 5; foreach ($map as $k => $v) { echo $k . ": " . $v . "\n"; }
O exemplo acima retorna:
A: 1 B: 2 C: 3 D: 4 E: 5
Outro exemplo, usando Pair:
<?hh $p = Pair {9, 'l'}; echo $p[0] . "\n"; echo $p[1] . "\n";
O exemplo acima retorna:
9 l
Nullable
Nullable introduz uma maneira mais segura de lidar com valores nulos. Isso nada mais é do que permitir qualquer tipo aceitar nulo, além dos valores normais para este tipo. É muito útil para os tipos primitivos que geralmente não permitem nulo como um de seus valores, como bool e int.
<?hh function check_not_null(?int $x): int { if ($x === null) { return -1; } else { return $x; } }
Chega de blá, blá, blá! O HipHop Virtual Machine, a.k.a HHVM, substitui servidores web como Apache e IIS com um serviço específico para PHP, buscando a performance perdida pela linguagem, mas, sem perder a praticidade.
Instalando o HHVM no Debian 7
$ wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add - $ echo deb http://dl.hhvm.com/debian wheezy main | sudo tee /etc/apt/sources.list.d/hhvm.list $ sudo apt-get update $ sudo apt-get install hhvm
Conferindo a versão do HHVM:
$ hhvm --version HipHop VM 2.4.2 (rel) Compiler: tags/HHVM-2.4.2-0-g432ecffa04b21c60953bb236a9db8278f4650537 Repo schema: 1be260b29a71097b5d1f78c6e4dcbb981ba03bde
Vamos dar uma olhada no server.hdf?
$ sudo nano /etc/hhvm/server.hdf
PidFile = /var/run/hhvm/pid Server { Port = 80 SourceRoot = /var/www/ DefaultDocument = index.php } Log { Level = Warning AlwaysLogUnhandledExceptions = true RuntimeErrorReportingLevel = 8191 UseLogFile = true UseSyslog = false File = /var/log/hhvm/error.log Access { * { File = /var/log/hhvm/access.log Format = %h %l %u % t \"%r\" %>s %b } } } Repo { Central { Path = /var/log/hhvm/.hhvm.hhbc } } #include "/usr/share/hhvm/hdf/static.mime-types.hdf" StaticFile { FilesMatch { * { pattern = .*\.(dll|exe) headers { * = Content-Disposition: attachment } } } Extensions : StaticMimeTypes } MySQL { TypedResults = false }
Não vou mudar nada por enquanto.
$ sudo touch /var/www/info.php $ sudo nano /var/www/info.php
Vamos dar uma olhada no phpinfo()? Insira <?hh phpinfo(); no seu info.php. Rodando:
$ sudo /etc/init.d/hhvm start $ hhvm /var/www/info.php HipHop
Você pode conferir no browser também
Bacana, né? Vamos ver um outro exemplo usando Vector:
<?hh class MyClass { private Vector<int> $vector = Vector{}; public function increment():Vector<int> { for($x=0;$x<10;$x++) { $vector[] = $x; } return $vector; } } $init = new MyClass(); var_dump($init->increment());
Temos o seguinte retorno:
array(10) { [0] => int(0) [1] => int(1) [2] => int(2) [3] => int(3) [4] => int(4) [5] => int(5) [6] => int(6) [7] => int(7) [8] => int(8) [9] => int(9) }
Bacana demais! Em outros artigos vou aprofundar mais no Hack, vamos falar de Hack Modes, Array, Shapes, Async, HHVM com Vagrant. Ufa, diversão garantida!