hack tutorial

85
Hack Tutorial 吉澤和香奈

Upload: wakana-yoshizawa

Post on 17-Jul-2015

1.517 views

Category:

Engineering


1 download

TRANSCRIPT

Hack Tutorial吉澤和香奈

自己紹介

↳ 吉澤和香奈↳ カツラじゃありません↳ 1987/6/30生まれO型↳ PHPに出会ったのは2012

年の夏です↳ HNは「wakana」「わかな

だょ〜」「ブ〜バ〜」等、気分により多数あります

Hackとは

Facebookが作った

PHPを拡張した

静的型検査する

プログラミング言語です

Facebookが作った

PHPを拡張した

静的型検査する

プログラミング言語です

→型に強いです

HHVMとは

PHP/Hackをバイナリコードに

変換させるVMです(HipHop Virtual Machine)

PHP/Hackをバイナリコードに

変換させるVMです(HipHop Virtual Machine)→読み込みが早くなります

HHVMで

PHPと

Hackの共存が実現できます!!

簡単に移行が実現できそうです

Tutorialやってみました

Hack Tutorial(公式)

http://hacklang.org/tutorial/2015/1/26現在のものです

Exercise 1

/***************************************************//****************** Hack Tutorial ******************/

/***************************************************/

/************ Click 'Next' to get started! *********/

Exercise 2

<?php// ^-- FIXME: replace <?php with <?hh

// A Hack file always starts with <?hh

<?hh// ^-- FIXME: replace <?php with <?hh

// A Hack file always starts with <?hh

Exercise 3

<?hh

// Hack functions are annotated with types.function my_negation(bool $x): bool { return !$x;}

// FIXME: annotate this function parameter// and return with the type 'int'.function add_one(/* TODO */ $x): /* TODO */ { return $x+1;}

<?hh

// Hack functions are annotated with types.function my_negation(bool $x): bool { return !$x;}

// FIXME: annotate this function parameter// and return with the type 'int'.function add_one(int $x): int { return $x+1;}

Exercise 4

<?hh

/* Hack errors come in multiple parts. * Hover over the underlined parts! */

function add_one(int $x): int { return $x+1;}

function test(): void { $my_string = 'hello';

// Some clever code ...

add_one($my_string);}

<?hh

/* Hack errors come in multiple parts. * Hover over the underlined parts! */

function add_one(int $x): int { return $x+1;}

function test(): void { $my_string = 'hello';

// Some clever code ...

add_one((int) $my_string);}

Exercise 5

<?hh

// Prefixing a type with '?' permits null.

// TODO: fix the type of the parameter $x to permit null.function f(int $x): void { var_dump($x);}

function test(): void { f(123); f(null);}

<?hh

// Prefixing a type with '?' permits null.

// TODO: fix the type of the parameter $x to permit null.function f(?int $x): void { var_dump($x);}

function test(): void { f(123); f(null);}

Exercise 6

<?hh

interface User { public function getName(): string; }

function get_user_name(?User $user): string {

if($user !== null) { // We checked that $user was not null. // Its type is now 'User'.

/* TODO: return $user->getName() */ } return '<invalid name>';}

function test(User $user) { $name1 = get_user_name($user); $name2 = get_user_name(null);}

<?hh

interface User { public function getName(): string; }

function get_user_name(?User $user): string {

if($user !== null) { // We checked that $user was not null. // Its type is now 'User'.

return $user->getName(); } return '<invalid name>';}

function test(User $user) { $name1 = get_user_name($user); $name2 = get_user_name(null);}

Exercise 7

<?hh

interface User { public function getName(): string; }

// There are many ways to handle null values.// Throwing an exception is one of them.

function get_user_name(?User $user): string {

if($user === null) { throw new RuntimeException('Invalid user name'); } /* TODO: return $user->getName() */}

function test(User $user) { $name1 = get_user_name($user); $name2 = get_user_name(null);}

<?hh

interface User { public function getName(): string; }

// There are many ways to handle null values.// Throwing an exception is one of them.

function get_user_name(?User $user): string {

if($user === null) { throw new RuntimeException('Invalid user name'); } return $user->getName();}

function test(User $user) { $name1 = get_user_name($user); $name2 = get_user_name(null);}

Exercise 8

<?hh

// Hack introduces new collection types (Vector, Set and Map).function test(): int {

// Vector is preferred over array(1, 2, 3) $vector = Vector {1, 2, 3};

$sum = 0; foreach ($vector as $val) { $sum += $val; }

return $sum;}

<?hh

// Hack introduces new collection types (Vector, Set and Map).function test(): int {

// Vector is preferred over array(1, 2, 3) $vector = Vector {1, 2, 3};

$sum = 0; foreach ($vector as $val) { $sum += $val; }

return $sum;}// Arrayよりも高速なVectorが使えます

Exercise 9

<?hh

// Hack uses generics for Collection types.

// TODO: fix the return type of the function 'test'function test(): Vector<string> { $vector = Vector {1, 2, 3}; return $vector;}

<?hh

// Hack uses generics for Collection types.

// TODO: fix the return type of the function 'test'function test(): Vector<string> { $vector = Vector {“1”, “2”, “3”}; return $vector;}

Exercise 10

<?hh

function vector_add1(Vector<int> $v): Vector<int> { // Example of lambda expressions. return $v->map($x ==> $x + 1);}

function vector_mult2(Vector<int> $v): Vector<int> { // TODO: write a function multiplying all the elements by 2}

<?hh

function vector_add1(Vector<int> $v): Vector<int> { // Example of lambda expressions. return $v->map($x ==> $x + 1);}

function vector_mult2(Vector<int> $v): Vector<int> { // TODO: write a function multiplying all the elements by 2 return $v->map($x ==> $x * 2);}

Exercise 11

/* * Congratulations! * You completed the beginner's tutorial. * * Click next to continue in expert mode. */

Exercise 12

<?hh

// All the members of a class must be initialized

class Point {

private float $x; private float $y;

public function __construct(float $x, float $y) { $this->x = $x; // FIXME: initalize the member 'y' }}

<?hh

// All the members of a class must be initialized

class Point {

private float $x; private float $y;

public function __construct(float $x, float $y) { $this->x = $x; // FIXME: initalize the member 'y' $this->y = $y; }}

Exercise 13

<?hh

// Check out this new syntax!// It's shorter and does the same thing ...

class Point {

public function __construct( private float $x, private float $y ) {}}

<?hh

// Check out this new syntax!// It's shorter and does the same thing ...

class Point {

public function __construct( private float $x, private float $y ) {}}// このような新しい書き方で今までより短くなります

Exercise 14

<?hh

// You can create your own generics!class Store<T> { public function __construct(private T $data) {} public function get(): T { return $this->data; } public function set(T $x): void { $this->data = $x; }}

// TODO: fix the return type of the function testfunction test(): Store<int> { $data = 'Hello world!'; $x = new Store($data); return $x;}

<?hh

// You can create your own generics!class Store<T> { public function __construct(private T $data) {} public function get(): T { return $this->data; } public function set(T $x): void { $this->data = $x; }}

// TODO: fix the return type of the function testfunction test(): Store<string> { $data = 'Hello world!'; $x = new Store($data); return $x;}

Exercise 15

<?hh

// You can specify constraints on generics.

interface MyInterface { public function foo(): void;}

// TODO: uncomment 'as MyInterface'// T as MyInterface means any object as long as// it implements MyInterfacefunction call_foo<T /* as MyInterface */>(T $x): T { $x->foo(); return $x;}

<?hh

// You can specify constraints on generics.

interface MyInterface { public function foo(): void;}

// TODO: uncomment 'as MyInterface'// T as MyInterface means any object as long as// it implements MyInterfacefunction call_foo<T as MyInterface>(T $x): T { $x->foo(); return $x;}

Exercise 16

<?hh

// The type 'this' always points to the most derived typeclass MyBaseClass { protected int $count = 0;

// TODO: replace 'MyBaseClass' by 'this' public function add1(): MyBaseClass { $this->count += 1; return $this; }}

class MyDerivedClass extends MyBaseClass { public function print_count(): void { echo $this->count; }}

function test(): void { $x = new MyDerivedClass(); $x->add1()->print_count();}

<?hh

// The type 'this' always points to the most derived typeclass MyBaseClass { protected int $count = 0;

// TODO: replace 'MyBaseClass' by 'this' public function add1(): this { $this->count += 1; return $this; }}

class MyDerivedClass extends MyBaseClass { public function print_count(): void { echo $this->count; }}

function test(): void { $x = new MyDerivedClass(); $x->add1()->print_count();}

Exercise 17

<?hh

// When a type is too long, you can use a type alias.type Matrix<T> = Vector<Vector<T>>;

function first_row<T>(Matrix<T> $matrix): Vector<T> { return $matrix[0];}

<?hh

// When a type is too long, you can use a type alias.type Matrix<T> = Vector<Vector<T>>;

function first_row<T>(Matrix<T> $matrix): Vector<T> { return $matrix[0];}// タイプが長い時は別名を指定出来ます

Exercise 18

<?hh

// Tuples represent fixed size arrays.// TODO: fix the return type.function my_first_pair((int, bool) $pair): int { list($_, $result) = $pair; return $result;}

<?hh

// Tuples represent fixed size arrays.// TODO: fix the return type.function my_first_pair((int, bool) $pair): int { list($result, $_) = $pair; return $result;}

Exercise 19

<?hh

// Shapes can be used for arrays with constant string keys.type my_shape = shape( 'field1' => int, 'field2' => bool,);

function first_shape(): my_shape { $result = shape('field1' => 1); // TODO: set 'field2' to the value true // on $result to complete the shape. return $result;}

<?hh

// Shapes can be used for arrays with constant string keys.type my_shape = shape( 'field1' => int, 'field2' => bool,);

function first_shape(): my_shape { $result = my_shape(1, true); // TODO: set 'field2' to the value true // on $result to complete the shape. return $result;}

Exercise 20

<?hh

// You can specify the types of functions too.function apply_int<T>((function(int): T) $callback, int $value): T { // TODO: return $callback($value)}

<?hh

// You can specify the types of functions too.function apply_int<T>((function(int): T) $callback, int $value): T { return $callback($value);}

Exercise 21

<?hh

// XHP is useful to build html (or xml) elements.// The escaping is done automatically, it is important to avoid// security issues (XSS attacks).

function build_paragraph(string $text, string $style): :div { return <div style={$style}> <p>{$text}</p> </div>;}

<?hh

// XHP is useful to build html (or xml) elements.// The escaping is done automatically, it is important to avoid// security issues (XSS attacks).

function build_paragraph(string $text, string $style): :div { return <div style={$style}> <p>{$text}</p> </div>;}// XHP記法でHTMLまたはXMLを構築することにより、クロスサイトスクリプティング対

策が実現できます

Exercise 22

<?hh

/* Opaque types let you hide the representation of a type. * * The definition below introduces the new type 'user_id' * that will only be compatible with 'int' within this file. * Outside of this file, 'user_id' becomes "opaque"; it won't * be compatible with 'int' anymore. */newtype user_id = int;

function make_user_id(int $x): user_id { // Do some checks ... return $x;}

// You should only use this function for renderingfunction user_id_to_int(user_id $x): int { return $x;}

<?hh

/* Opaque types let you hide the representation of a type. * * The definition below introduces the new type 'user_id' * that will only be compatible with 'int' within this file. * Outside of this file, 'user_id' becomes "opaque"; it won't * be compatible with 'int' anymore. */newtype user_id = int;

function make_user_id(int $x): user_id { // Do some checks ... return $x;}

// You should only use this function for renderingfunction user_id_to_int(user_id $x): int { return $x;}// user_idタイプを作る事により、このファイルで型を管理し、他のファイルではuser_id型になります

Exercise 23

<?hh

class MyBaseClass { // TODO: fix the typo in the name of the method. public function get_uuser(): MyUser { return new MyUser(); }}

class MyDerivedClass extends MyBaseClass { /* <<Override>> is used to specify that get_user has been inherited. * When that's not the case, Hack gives an error. */ <<Override>> public function get_user(): MyUser { return new MyUser(); }}

<?hh

class MyBaseClass { // TODO: fix the typo in the name of the method. public function get_user(): MyUser { return new MyUser(); }}

class MyDerivedClass extends MyBaseClass { /* <<Override>> is used to specify that get_user has been inherited. * When that's not the case, Hack gives an error. */ <<Override>> public function get_user(): MyUser { return new MyUser(); }}

Exercise 24

<?hh

class C { protected function bar(): void {} }interface I { public function foo(): void; } // 'require' lets you specify what the trait needs to work properly.trait T {

// The class using the trait must extend 'C' require extends C;

// TODO: uncomment the next line to fix the error // require implements I;

public function do_stuff(): void { $this->bar(); // We can access bar because we used "require extends" $this->foo(); }}

<?hh

class C { protected function bar(): void {} }interface I { public function foo(): void; } // 'require' lets you specify what the trait needs to work properly.trait T {

// The class using the trait must extend 'C' require extends C;

// TODO: uncomment the next line to fix the error require implements I;

public function do_stuff(): void { $this->bar(); // We can access bar because we used "require extends" $this->foo(); }}

// Congratulations! You are done!

次回やりたいこと

1. WordPressを移行してみる2. Hackで書き直す3. ベンチマークを取って比較する

アップデート出来なくなるのでコピーで作業します (;´Д`)

ご清聴ありがとうございました