こんにちは、開発本部の松浦です。先日開催されたPHPカンファレンス2023にて、PR TIMESはゴールドスポンサーとして協賛し、スポンサーブースとして出展しました。
今回は、ブース企画の裏側やPHPの問題コードの解説について書いていこうと思います!
今回作成した問題の解説
解答はPR TIMES開発本部のXアカウント(旧Twitter) @prtimes_dev にて公開しました。まずはその解答をより詳しく解説していこうと思います。企画の問題のコードは下記で、構文エラー・バグの箇所は全部で6箇所でした。
<?php // E_ALL, PHP7.4
declare(strict_types=1);
class SortMachine {
private array $array = 'array'; // <- 1. array型なのに、文字列を入れてしまっているのでエラー
private int $size = 0;
public function __construct(array $array) {
$this->array = array_values($array);
$this->size = count($array);
}
public function sort(string $alg): array { // <- 2. $algが'bubble', 'bogo'以外の場合、型がnullになるのでエラー
switch($alg) {
case 'bubble': return $this->bubbleSort();
case 'bogo' : return $this->bogoSort();
}
}
private function bubbleSort(): array {
for ($i = 0; $i < $this->size; $i++) {
for ($j = 1; $j < $this->size - $i; $j++) {
if ($array[$j-1] > $array[$j]) { // <- (3. 存在しない$arrayを参照している)
[$array[$j-1], $array[$j]] = [$array[$j], $array[$j-1]];
}
}
}
return $array; // <- 3. 存在しない$arrayを参照しているためエラー
}
private function bogoSort(): int { // <- 4. 戻り値がarrayを想定しているのに、int型になっている
$array = $this->array;
while(true) {
$array = shuffle($array); // <- (5. 32行目でarray型として初期化されているのに、bool型が代入されている)
for($i = 1; $i < $this->size; $i++) {
if ($array[$i-1] > $array[$i]) continue 2;
}
break // <- 6.セミコロン入れ忘れ;;
}
return $array; // <- 5. shuffle関数の戻り値はboolなので、型不一致となりエラー
}
}
1. array型なのに、文字列を入れてしまっているのでエラー
こちらはタイトル通りのエラーです。この箇所が一番正答率が高かった箇所でした。なお、PHP7.4以降からclassプロパティにプリミティブ型をつけることができるようになりました。 (参考: https://www.php.net/manual/ja/migration74.new-features.php#migration74.new-features.core.typed-properties)
修正例は’array’
を[]
にすると動作します。
2. $algが’bubble’, ‘bogo’以外の場合、型がnullになるのでエラー
ここもタイトル通りのエラーです。switch文内にdefaultを追加して、array型を返すようにすると修正できます。breakがないと次のcaseが実行されてしまうというswitch文の仕様がありますが、今回の場合returnしているのでbreakはなくても良いです。
3. 存在しない$arrayを参照しているためエラー
バブルソートのロジックにバグがあるのではないかと探していた方は多かったと思います。実はそもそも$arrayが宣言されていないものでした。修正例は、最初のfor文前に$array = $this->array;
を追加すると動作します。
4. 戻り値がarrayを想定しているのに、int型になっている
こちらもタイトル通りですね。array型を想定しているのでintの部分をarrayに修正すると動作します。
5. shuffle関数の戻り値はboolなので、型不一致となりエラー
PHPの標準関数であるshuffle関数をよく知っていないとわからないようなエラーだったので、一番難しい箇所だったかと思いましたが、何人か指摘してくださいました。こちらのshuffle関数は参照渡しで、戻り値には成功か失敗かのbool値が返ります。よって、$arrayがbool型になり型エラーとなります。(参考: https://www.php.net/manual/ja/function.shuffle.php) この場合は$arrayに代入する処理を削除すると動作します。
6.セミコロン入れ忘れ;
最近ではセミコロンをつけない言語もあるので、それを行き来しているとやってしまいがちなエラーですね。エディタがあればすぐに見つけられる構文エラーでした。;
ブース企画までの道のり
ここからは、ブースの企画までの道のりについてです。
私自身、ブースの企画は初の挑戦でした。
右も左も分からない状態だったので、ブース企画担当は私とmeiheiさんで進めました。直近で開催されたPHPerKaigi2023でのブースでは福引き機をやりましたが、たくさんの来場者に楽しんでもらえるような別の企画にしたいというのが、チームメンバー一致の思いでした。
どんなブース企画にしようか考えていた中、meiheiさんから「iOSDCでLINE株式会社(現LINEヤフー株式会社)が企業ブースでやられていた、付箋でコードレビューみたいな企画をしよう!」という案が出ました。
最初、私は「めちゃくちゃ面白そうな企画じゃん!」と思いましたが、柔軟にレビューの解説・判定ができる知識や経験が必要なこと、問題の難易度調整が難しいといった課題がありました。
正直、色々と厳しそうだったので別の企画にしようかとも悩みました。ただ、個人的に面白い企画だと思っていたのでなんとかやりたい気持ちでした。そこから、上記の企画を元に解説・判定や問題難易度調整がしやすいものにして企画をブースでやろう!と決めました。
ブース企画完成へ
まずは問題内容を正解か不正解か判定しやすいように、コード内に構文エラーやバグを見つけるといったシンプルな企画にしました。
それに伴って運用ベースも下記のように変更しました。
- 問題コードをブース前に貼ると解きづらいので、バインダー上の問題用紙からペンを使って誤りを指摘するように変更。
- ある一定数のバグや構文エラーを見つけることができれば、景品を渡す。
- 解き終わったらヒントや感想などを付箋で残すことが出来るようにする。
最後に、企画を進めていく中で一番悩んだのが問題用のPHPコードでした。PHPをよく知っていないと解けないようなバグや構文エラーや複雑なロジックだと、解説する側の負担が大きくなったり、難易度が上がってノベルティが残りすぎてしまうといった問題を考慮する必要がありました。
そこで私はプログラミングをやったことある人だったら誰しもが知るものが良いと思い、「ソートアルゴリズム」に着目しました。先輩のmeiheiさんやPHPのスペシャリストであるuzullaさんの監修の元、試行錯誤を重ねて問題を作成することができました。
カンファレンスまで残り2週間程度の中、ブース運営マニュアルの作成も兼ねてなんとか企画完成まで持っていくことができました!
終わりに
以上のようにして、ブース企画を完成させることができました。当日のブースでは160人程の方が問題へ挑戦してくださりました。ありがとうございました。お楽しみいただけたのなら何よりです!同時にさまざまな改善点を見つけることができたので、次回の企画や運営へ繋げていこうと思います。
最後に、当日のブース運営・ノベルティなど準備してくださったチームメンバーの皆様、そしてブース企画や問題コード作成に協力してくださったmeiheiさん、uzullaさん、本当にありがとうございました!