IT社畜犬くわっちょのはてな

渋谷の片隅で働く、フルスタックエンジニアに憧れる器用貧乏なIT社畜犬の遠吠え

input type="number" 用のmaxlength指定処理を作ってみた。

こんな感じで

$('input[type="number"]').on('input', function () {
    var regex = new RegExp(/^[0-9]+$/);
    var regexDecimal = new RegExp(/^([1-9][0-9]*|0)(\.[0-9]+)?$/);
    if ($(this).val().length > $(this).attr('maxlength')) {
        $(this).val($(this).val().slice(0, $(this).attr('maxlength')));
    } else if (parseInt($(this).val(), 10) != 0 && !parseInt($(this).val(), 10)) {
        $(this).val('');
    } else if (parseInt($(this).val(), 10) < parseInt($(this).attr('min'), 10)) {
        $(this).val($(this).attr('min'));
    } else if (parseInt($(this).val(), 10) > parseInt($(this).attr('max'), 10)) {
        $(this).val($(this).attr('max'));
    } else if (typeof $(this).attr('decimal') === "undefined" && !regex.test($(this).val())){
        $(this).val(parseInt($(this).val(), 10));
    } else if (typeof $(this).attr('decimal') !== "undefined" && !regexDecimal.test($(this).val())){
        $(this).val(parseFloat($(this).val()));
    }
});

今のところいい感じには動いてる。

FuelPHPのcoreのerrorhandler.phpがErrorhandlerを継承していない?

未だにこれの謎が解けぬ……なんなのだろう? ネームスペースの問題だとは思うが……

PHP Fatal error:  Uncaught Exception: File "COREPATH/classes/errorhandler.php" does not contain class "Fuel\Core\Errorhandler" in /hoge/fuel/core/classes/autoloader.php:397
Stack trace:
#0 /hoge/fuel/core/classes/autoloader.php(236): Fuel\Core\Autoloader::init_class('Fuel\\Core\\Error...', '/vagrant_data/i...')
#1 [internal function]: Fuel\Core\Autoloader::load('Fuel\\Core\\Error...')
#2 [internal function]: spl_autoload_call('Fuel\\Core\\Error...')
#3 /hoge/fuel/core/classes/autoloader.php(247): class_alias('Fuel\\Core\\Error...', 'Errorhandler')
#4 [internal function]: Fuel\Core\Autoloader::load('Errorhandler')
#5 /hoge/fuel/core/bootstrap.php(71): spl_autoload_call('Errorhandler')
#6 [internal function]: PHPUnit_Util_Fileloader::{closure}()
#7 {main}
  thrown in /hoge/fuel/core/classes/autoloader.php on line 397
PHP Stack trace:
PHP   1. {main}() /usr/local/bin/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() /usr/local/bin/phpunit:583
PHP   3. PHPUnit_TextUI_Command->run() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:118
PHP   4. PHPUnit_TextUI_TestRunner->doRun() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:188

Fatal error: Uncaught Exception: File "COREPATH/classes/errorhandler.php" does not contain class "Fuel\Core\Errorhandler" in /hoge/fuel/core/classes/autoloader.php on line 397

Call Stack:
    0.0009     495536   1. {main}() /usr/local/bin/phpunit:0
    0.2010   10224488   2. PHPUnit_TextUI_Command::main() /usr/local/bin/phpunit:583
    0.2010   10227648   3. PHPUnit_TextUI_Command->run() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:118
    1.4838   14664928   4. PHPUnit_TextUI_TestRunner->doRun() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:188

Exception: File "COREPATH/classes/errorhandler.php" does not contain class "Fuel\Core\Errorhandler" in /hoge/fuel/core/classes/autoloader.php on line 397

Call Stack:
    0.0009     495536   1. {main}() /usr/local/bin/phpunit:0
    0.2010   10224488   2. PHPUnit_TextUI_Command::main() /usr/local/bin/phpunit:583
    0.2010   10227648   3. PHPUnit_TextUI_Command->run() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:118
    1.4838   14664928   4. PHPUnit_TextUI_TestRunner->doRun() phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:188
   86.1126   41742880   5. PHPUnit_Util_Fileloader::{closure:/hoge/fuel/core/bootstrap.php:34-72}() /hoge/fuel/core/bootstrap.php:0
   86.1129   41743200   6. spl_autoload_call() /hoge/fuel/core/bootstrap.php:71
   86.1129   41743240   7. Fuel\Core\Autoloader::load() /hoge/fuel/core/bootstrap.php:71
   86.1153   41743440   8. class_alias() /hoge/fuel/core/classes/autoloader.php:247
   86.1154   41743488   9. spl_autoload_call() /hoge/fuel/core/classes/autoloader.php:247
   86.1154   41743536  10. Fuel\Core\Autoloader::load() /hoge/fuel/core/classes/autoloader.php:247
   86.1154   41743632  11. Fuel\Core\Autoloader::init_class() /hoge/fuel/core/classes/autoloader.php:236

今更ながら改めてJavaのLongの比較を試してみた。

ソースレビューをしていた時にふと気づいたこと

  Long a = 1L;
  Long b = 1L;

があったとして、このLong値が一致するかどうかというのを

  if (a == b) {}; // 1.
  if (a.equals(b)) {}; // 2.

と比較方法が書く人によってバラバラなことに気付く。
まあ、ラッパークラスなので2.の方がいいというのはいいんだが、1.でも問題なく動いていたりするのでどうにも指摘しにくい。
というより自分自身Longの場合に上記の違いをちゃんと学んどこうと思ったのでちょっと試してみた。

まず作ったのはこんなコード

public class LongTest {

    public static void main(String[] args) {
        Long a = 1L;
        Long b = Long.valueOf("1");

        // a と b の比較
        if (a == b) {
            System.out.println("[a == b] true");
        } else {
            System.out.println("[a == b] false");
        }
        if (a.equals(b)) {
            System.out.println("[a.equals(b)] true");
        } else {
            System.out.println("[a.equals(b)] false");
        }
    }

}

で実行結果

[a == b] true
[a.equals(b)]  true

とどっちもtrueになったのでなんともしっくりこない。

とこんなことをコードと共にしっくりこないことを呟いたところ以下の指摘をいただく。

実際Longのコードを見てみると確かに

    public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }
    
    private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }

とある。なるほどな。

.longValue()でプリミティブ型に変換して比較する、という指摘もいただいたので2種類試してみる。

まず第1弾。値を1でやってみる。

public class LongTest {

    @SuppressWarnings("unused")
    public static void main(String[] args) {
        Long a = 1L;
        Long b = Long.valueOf("1");
        Long c = new Long(1L);
        Long d = null;

        // a と b の比較
        if (a == b) {
            System.out.println("[a == b] true");
        } else {
            System.out.println("[a == b] false");
        }
        if (a.equals(b)) {
            System.out.println("[a.equals(b)] true");
        } else {
            System.out.println("[a.equals(b)] false");
        }

        // a と c の比較
        if (a == c) {
            System.out.println("[a == c] true");
        } else {
            System.out.println("[a == c] false");
        }
        if (a.equals(c)) {
            System.out.println("[a.equals(c)] true");
        } else {
            System.out.println("[a.equals(c)] false");
        }

        // b と c の比較
        if (b == c) {
            System.out.println("[b == c] true");
        } else {
            System.out.println("[b == c] false");
        }
        if (b.equals(c)) {
            System.out.println("[b.equals(c)] true");
        } else {
            System.out.println("[b.equals(c)] false");
        }

        // .longValue() をつける
        if (a.longValue() == c.longValue()) {
            System.out.println("[a.longValue() == c.longValue()] true");
        } else {
            System.out.println("[a.longValue() == c.longValue()] false");
        }
        if (b.longValue() == c.longValue()) {
            System.out.println("[b.longValue() == c.longValue()] true");
        } else {
            System.out.println("[b.longValue() == c.longValue()] false");
        }

        // a と null の比較
        if (a == d) {
            System.out.println("[a == d] true");
        } else {
            System.out.println("[a == d] false");
        }
        if (a.equals(d)) {
            System.out.println("[a.equals(d)] true");
        } else {
            System.out.println("[a.equals(d)] false");
        }
    }

}

で実行結果

[a == b] true
[a.equals(b)]  true
[a == c] false
[a.equals(c)]  true
[b == c] false
[b.equals(c)]  true
[a.longValue() == c.longValue()] true
[b.longValue() == c.longValue()] true
[a == d] false
[a.equals(d)] false

なるほど確かにnewするとfalseになるな。

で第2弾。値を128でやってみる。

public class LongTest2 {

    public static void main(String[] args) {
        Long a = 128L;
        Long b = Long.valueOf("128");
        Long c = new Long(128L);

        // a と b の比較
        if (a == b) {
            System.out.println("[a == b] true");
        } else {
            System.out.println("[a == b] false");
        }
        if (a.equals(b)) {
            System.out.println("[a.equals(b)]  true");
        } else {
            System.out.println("[a.equals(b)] false");
        }

        // a と c の比較
        if (a == c) {
            System.out.println("[a == c] true");
        } else {
            System.out.println("[a == c] false");
        }
        if (a.equals(c)) {
            System.out.println("[a.equals(c)]  true");
        } else {
            System.out.println("[a.equals(c)] false");
        }

        // b と c の比較
        if (b == c) {
            System.out.println("[b == c] true");
        } else {
            System.out.println("[b == c] false");
        }
        if (b.equals(c)) {
            System.out.println("[b.equals(c)]  true");
        } else {
            System.out.println("[b.equals(c)] false");
        }

        // .longValue() をつける
        if (a.longValue() == c.longValue()) {
            System.out.println("[a.longValue() == c.longValue()] true");
        } else {
            System.out.println("[a.longValue() == c.longValue()] false");
        }
        if (b.longValue() == c.longValue()) {
            System.out.println("[b.longValue() == c.longValue()] true");
        } else {
            System.out.println("[b.longValue() == c.longValue()] false");
        }

    }

}

で実行結果

[a == b] false
[a.equals(b)]  true
[a == c] false
[a.equals(c)]  true
[b == c] false
[b.equals(c)]  true
[a.longValue() == c.longValue()] true
[b.longValue() == c.longValue()] true

なるほどたしかにnewしなくても == も通らなくなったね。

これを踏まえ処理を見直してみたところ、今回の場合==でも問題が発覚しなかったのは、Longで型を指定しているにも関わらず値が100以下がほとんどだったためという事もわかった。
まあ、バグの温床になってしまうのでequalsを使うように修正。
ラッパークラスがプリミティブ型とおなじような比較をある程度サポートしてくれているとはいえ、安易にそれに頼ってはいけないと改めて気づかされた次第。

Jacksonで無理やりJSONの空オブジェクトを作った話

{
  "foo": "inu",
  "bar": {}
}

こんなjsonJava、というかJacksonで作りたくて
空のObjectをそのまま渡すとエラーとなるので以下のような形で無理やり空クラスを定義してそれを突っ込むことで
上記のようなjsonを作る事に成功したのだけれど本当にこれでよかったのだろうか?
ツッコミ求む。

@JsonIgnoreProperties(ignoreUnknown = true)
public class EmptyJsonObject {
  @Override
  public String toString() {
    return "{}";
  }
}

ソシャゲという点からみた艦これの位置付け

ディズニー・ツムツムから見たソーシャルゲーム/スマホゲームの問題点

こちらの記事について

艦これユーザーの視点から何か意見はないかとリクエストされたのでちょっと書いてみます。 といっても、犬はソシャゲの開発や運営には携わったことないのと、艦これ以外のソシャゲほとんどやったことない(ただしアケマスは昔相当やりこんでた。後述)ので 完全に犬の主観であり、感想となりますこと先にご容赦ねがいます。

ちなみにソシャゲの流れとかについては元記事の方が詳しいので詳しくは割愛。必要なところは元記事より引用していきます。

前提:そもそも艦これのルールとは


まず艦これとは、第二次世界大戦時の旧大日本帝国海軍 + 他複数国の軍艦をいわゆる萌え擬人化した「艦娘」をゲーム内で集め、育て、敵である深海棲艦を倒していくというのが基本的な流れです。 ゲーム自体はDMM.comのアカウント + DMMオンラインゲームのアカウントがあれば基本的に無料でプレイできます。 ※ただし、DMMオンラインゲーム自体が18歳未満は利用不可なので実質18歳以上という年齢制限あり ⇒ DMMオンラインゲーム利用規約

ちなみに艦これは、この記事を書いている2015/09/19時点では無抽選常時新規着任開放してますが、数か月前までは抽選制でした。 なので新規プレイは今であればできるはずです。(将来的に抽選制に戻る可能性はあり)

でもって着任した後の流れとしては次のようになります。

  • 初期艦を「吹雪」「叢雲」「」「」「五月雨」の中から一人選ぶ
  • 初期艦以外の艦娘はゲーム内で「建造」するか「出撃」後のドロップで入手する
  • ゲーム内でプレイヤーは「燃料」「弾薬」「鋼材」「ボーキサイト」の4つの資材を持っており、これを消費することで出撃や建造、ダメージを受けた艦娘の入渠(HP回復に相当。ただし時間が必要。後述)を行う。
  • 出撃した艦娘には経験値が入り、これが一定量たまるとレベルアップし、能力が上昇する。
  • 出撃 + 建造 orドロップで艦娘を集め、艦隊を編成して深海棲艦を倒していく。
  • ゲーム内には複数の海域があり、各海域のボスを倒していく事で次の海域が解放される。
  • 海域毎にドロップできる艦娘が変わる。後半海域の方がよりレアな艦娘が登場するため全部集めようと思ったら後半までいく必要あり。
  • 艦娘を轟沈(HPが0の状態)させてしまうと二度とその艦娘は戻らない(建造やドロップで入手できる場合もある)。

というところでしょうか。 空母や戦艦といった艦種の特徴や、その他詳しいルールとか各種パラメータの説明は攻略wikiの方が詳しいので割愛します。

艦これの楽しさはどこにあるか


これ自体は人それぞれだと思います。

  • いわゆるキャラ萌え。初雪は俺の嫁
  • 艦これは史実の艦の情報を知っているとニヤリとするようなネタがふんだんに盛り込まれているので、ミリタリー的な意味での萌え。引きこもりキャラなのに史実では奮闘しまくりな初雪は俺の嫁
  • 公式に「兵站ゲーム」と言われるくらいに兵站の重要な戦術シミュレーションゲームという側面(ただしプレイヤーにできるのは出撃前の装備の選択と誰を出撃させるかという選択だけ。戦闘自体は基本見てるだけ)

艦娘は2015/09/19現在164人(※)が実装されており、1人1人が見事にキャラも個性も異なるので、そのあたりが魅力の大きさたるものかと思います。 ※種類になるともっと多いです。これは艦種が変わったり名前が変わる艦娘も1人でカウントした値

しかし、艦これには他ソシャゲとは大きく異なる特徴が3つあります。 * 他ソシャゲで一般的なガチャのシステムがない * 完全無課金でもほとんどの艦娘が手に入る ※建造や通常海域でのドロップが未実装の艦娘は約10人ほど存在する * リアルマネーをいくらつぎ込んでも、目当ての艦娘に出会える保証はない。運要素が非常に強い

犬的には、これは時間さえあればだれでも確実に勝てることが保証されているゲームだという解釈です。 そして犬的には、ここが艦これの一番の魅力だと思ってます。

時間さえあれば誰でも強くなれるシステム


通常のソシャゲは強いカードやキャラというのはリアルマネーで購入できる何等かのアイテムを用いていわゆるガチャを回して手に入れるのが一般的です。 その代わり、例えば10回以上回したら確実にレアなカードが入ってます、といったように確実に強いカードを手に入れる保証があります。 逆にリアルマネーがないといくら頑張っても限界があります。強くなりたいなら如何にリアルマネーをつぎ込むかがカギとなります。 逆に運営側としては、それをどのように調整、配分するかでそのゲームの特徴を作っていきます。 主観ですがミリマスやデレマスはその傾向が強いように思います。

これに対し艦これは前述のようにこのガチャという仕組みはありません。 艦これでも目当ての艦娘を出すための仕組みとして建造があるのですが、この建造にはゲーム内の資源を消費する必要があります。 しかし、この資源、実は『時間と共に一定量まで回復する』仕組みになっています。 その最大値も出撃し敵を倒せば倒す程増えていく仕組みになっています。 なので、時間さえあれば建造は確実にできるし、いわゆるレシピを知っていればレアな艦娘や強い艦娘が手に入ることになります。 ゲーム内のアイテムを消費してキャラクターを出すという仕組みはガチャとよく似てはいますが、艦これの場合は課金が必要なことを前提としていない点で違いがあります。 建造に必要なアイテムや資材はゲーム内の任務をこなしていくことでたまっていきますし、出撃ドロップも資材さえあれば狙えます。

繰り返しになりますが、この資材が時間があれば課金しなくても確実に手に入る事が艦これの特徴です。 なので艦これはこの資材をどのように計画的に使い、自らの艦隊を充実させていくかという点を非常に考えるゲームになっています。

ただこの建造にしても、出撃ドロップにしても、『目当ての艦娘が手に入る保証はどこにもない』のです。 レアかつ強い艦の代表である雪風島風はドロップ、建造ともに可能ですが、でない時はいくら資材を投入してもでませんし、いくら出撃してもでません。 逆にどちらも1回で出る人もいます。 艦これは目当ての艦娘が「確実に出る」保証はどこにもないのです。 しかし「頑張ればいつかは無課金でも出る」ことは保証されてます。 なのでプレイヤーたちは時間で回復する資源をうまくやりくりしながら誰を手に入れるか頭を悩ませることになるのです。

他のソシャゲは「確実に自分を強くするために」あるいは「確実にクリアできるようにするために」リアルマネーを必要とします。 逆にリアルマネーがないと「どんなに頑張っても強くなれない」システムでもあります。

これに対し艦これはリアルマネーがあっても確実に自分が強くなれるシステムではありません。上記の通り、運要素が強いからです。 ではこの運要素を乗り越え目当ての艦娘を手に入れ、敵海域を突破するためにはどうすればいいか? 答えは単純。「他のソシャゲ以上に何度も試行する」しかないのです。

犬的にはこの「他のソシャゲ以上に何度も試行する」ことをプレイヤーに自然に要求する仕組みが出来上がっていることが艦これの特徴であり、強みだと思っています。 そして、試行した分だけ無課金でも確実に強くなれることが保証されているのです。 また、艦これでは他プレイヤーと競うという概念があまりなく、戦果を競うという側面はありますが、戦果報酬で得られるものも所謂先行実装された装備であり、将来的には他の手段で手に入る可能性があるものなので無理に他プレイヤーと競う必要もないのです。

そして、この「他のソシャゲ以上に何度も試行する」システム自体が艦これにおける課金の重要性を生み出していることになります。 艦これ内において何度も試行するという事は、ゲーム内の資材を使い、建造し、出撃し、ダメージを受けたら入渠させ、それを繰り返して艦娘を育て次の海域に挑む。この繰り返しです。 艦これにおける課金はこれを助けるために存在します。資材をためる時間、建造にかかる時間、ダメージを受けた艦娘を回復させる時間、これをほぼ0にするためのアイテムを買うためにリアルマネーが必要になってきます。

艦これは時間をお金で買うシステムが強調されている


艦これは資材を手に入れる為にも、新たな艦娘を手に入れるためにも、とにかく時間を必要とします。 この時間というのはリアルに待てばいいのですが、忙しい現代人にはなかなかそれができません。 特にイベントが始まった場合は限定の艦娘だったり装備だったりを手に入れるためにいつも以上に試行回数が必要になります。

この試行回数を増やすためには資材が必要になりますし、入渠した艦娘を一瞬で回復させるための高速修復材(いわゆるバケツ)が必要になります。 この資材もバケツも課金で手に入れることができます。いずれも時間さえあれば手に入る手段はあるのですが、それよりも時間を惜しむ場合はリアルマネーを使う事になります。

また入渠のためのドックも、最初は2つしかありません。課金することで4つまで増やせます。 ドックを増やす事でトータルの修理時間を減らし、素早く次の海域へと出撃していくことができるようになります。 その為にもやはりリアルマネーが必要になります。

建造にも大和や武蔵といった最強クラスの艦娘は「大型艦建造」というより大量に資材を消費する仕組みでしか手に入らないというケースがあります。 この大型艦建造も最後は試行回数です。これに必要になる資材をとにかく1秒でも早く欲しいとなれば、リアルマネーに手を出す必要があります。 ※といっても大和や武蔵を出すために必要な金額は軽く10万は超えるでしょうが...

ただし、これはあくまでも時間が惜しければの話です。 艦これは時間さえあれば必要なアイテムはゲーム内で必ず手に入ります。なので無理に課金する必要はないのです。 逆に無理に課金しなければならない状況になったということは、それだけ時間が惜しい事を意味します。 艦これにおいてリアルマネーをかけることは現実の時間をお金で買っているのです。

リアルマネーによらず強くなれる仕組みの本質


最近のソシャゲはどちらかというとリアルマネーを払ったプレイヤーが強く、そうでないプレイヤーは弱いという立場になりがちです。 これに対し、艦これはソシャゲのよい部分は残しつつ、旧来のゲームにあった「時間をかければ誰でも確実に強くなれる」という面が強調されていると思います。 この時間もリアルマネーでどうにかできる部分はありますが、必ずしもそれを要求するバランスにはなっていないことも伸びた理由でしょう。

ソーシャルゲーム自体の構造が本当にこれでいいのかどうかの考察とかは元記事の方が詳しくやっている上に長いのでここでは割愛します。 ちなみに、元記事で指摘されているようなソシャゲの構造的な問題点についてははっきりいって艦これにもほぼ同様の事が言えます。 ただ "しかも、その提供側は世界を支配している。トッププレイヤーが何百時間を費やし、ついに獲得した技芸を無意味なものにしてしまうのも容易い。「さぁ、圧倒的な存在などなくなりました、まだまだチャンスがあります」というわけだ。"という他のソシャゲで多々見られるこの展開は艦これにはあまり当てはまりません。 そもそも艦これは先行ユーザーが後発参入者よりも絶対的に有利になる状況はほぼありません。 せいぜい未だ通常海域に実装されてない装備や艦娘を先に手に入れられるということくらいで、これはゲーム自体のバランスを絶対的に崩すものではありません。 ゲーム的な意味で強い艦娘の大半は後発参入者にも確実に手に入るようになっています(例外としては秋月、照月、プリンツ・オイゲンくらい)。 他人と争うメリットがあまり大きくないシステムを採用している艦これでは、後発参入者にとっても優しいゲーム体系だといえます。 "基本的に現在のトッププレイヤーを基準してルールが変更されていく。ほとんどの場合、新規参入者は歯牙にもかけられず、その競争には加われない、そもそも楽しめないようにしてしまう。"というのが主流なソシャゲ界隈においてはその競争にある程度のレベルまで達すれば後発参入者でも容易に参加できる艦これは易しい方だと思います。

ただし"クリアしてしまえば、やめてしまう可能性が高いし、満たされてしまえばそれ以上支払わない。だから、次々と目標を提示する。「ミッションがありますよ!」「これをクリアしたらこれがもらえますよ!」そうして、各々のプレイヤーが思い描いていたゴールや楽しみ方を剥奪し、遠くにゴールを設定してそれを目指せと煽る。"という点があるのは事実です。 イベント海域などはいい例ですね。 ただそのゴールが「なければないで構わない」「また次がある」と言える空気があるのが艦これのいいところではあると思います。 ※ただ前述の秋月型姉妹やプリンツ・オイゲンという大きな例外もあるので微妙なとこですが……

まとめると

  • 後発参入者にもチャンス(無実化されたものではない。これ重要)がある
  • 時間と本人の努力次第で強くなれるという旧来のゲームのいい部分を部分的に引き継いでいる
  • 上記の時間を補うための仕組みは別途用意されている。これをリアルマネー形式にすることで運営側にとっての収益モデルとなりえる。

という、過度に課金主義にならず、それでいてユーザーにとって確実に楽しめる形式を産み出し、運営側にとっても確実な収益を生み出せるモデルケースが艦これなのだと思います。

余談:本質を忘れた点がないわけではない


ただ最近行われたイベントでは上記の本質を見失いつつある事態が起きていたことも事実です。

  • イベントのラスボス撃破に必要な非常にわかりにくいギミックの導入
  • イベント後半海域の報酬艦が照月とバランスブレイカー的な艦娘の為、後発参入者にとっての不利につながる。
    • 一応摩耶改二や五十鈴改二、初霜改二という代替手段はあるものの……
  • 前イベントの報酬艦である秋津洲がいる前提の海域の増加やイベント海域の実装

たしかにソシャゲそのものが運営側に大きな裁量があるのは事実ですが、後発参入者にもチャンスがあるのが艦これの魅力だと思っているので、この点を忘れずにいい意味で平等に機会は与えられているという事は守ってほしいものです。 まあこの「機会は平等」というのがギャンブル的要素を含んでいるのも事実かもしれませんが……

犬が思うコンピュータアクセシビリティの壁と対策

犬はいわゆる文系SEです(・ω・U)。
もともと犬は特別支援教育を専攻しており、一応「特別支援学校免許状」も持っています(さび付いてますが)。

なぜそのような分野を専攻し、そしてSEになったのかは今回のネタではないので省きますが、
昨日のTadashiさんのスライドを見て
両方の分野に一時的にでもかかわってきたから思った事を短いですが書きます。

壁はどこか?


  • 手話通訳者の確保はかなり困難。専門教育を受けていても難しい 参考:手話通訳技能認定試験(手話通訳士試験)過去の合格率
  • アクセシビリティノーマライゼーションについて専門教育を受ける人間は支援の専門家にはなれても「エンジニアとしては」専門家ではない
  • そのエンジニアになるにもアクセシビリティノーマライゼーションについて学ぶ時間をほぼ同等の時間が必要
    • 合計すると最低でも4年。普通は6~8年は必要。
  • 障がい者とITの両方に知識を持つ人間が絶対的に不足しているので、高等教育機関による教育も現状不可能に近い
  • エンジニアにとっても障がい者支援側にとっても「各分野で必要になる知識が非常に膨大」で「両方を体系的に学べる期間を確保するのが社会人になってからは難しい(片方はどうにか可能)」という壁がある
    • 知識が膨大であるなら、早い段階から学んでいく方がいい
    • 両方をまとめて学べる大学が不足しているのも現実

考える対策


  • アクセシビリティについて教える教育者が必要
    • システム、アクセシビリティノーマライゼーションについて横断的に詳しいエンジニアが必要
    • 障がい者支援側がエンジニアになるのは不可能ではないが、「支援者の数 < エンジニアの数」 なのでエンジニア側を教育する方がいい
    • そのエンジニアを中心に高等教育プログラムの立ち上げがいる
  • できるだけ早い段階から教育する。
    • 高校でエンジニアの基礎教育。大学でソフトフェア工学とアクセシビリティについて学ぶようなコースを作る
    • 既存のソフトウェア工学特別支援教育を学ぶ学科の一部としてではなく、独立した学科として教育を実施する
    • 会社入社後は会社、周囲の理解がないと改めて教育機関で学ぶのは困難に近い。できる限り18~22歳ごろの教育で育成するべき。
  • ノーマライゼーションについて推し進める企業に対するエンジニアの採用支援と費用支援
    • ただでさえ人手不足のIT業界でエンジニアにも企業側にも支援なしで民間頼みにするのは危険。
    • 人材教育・確保の費用の補助を国や地方公共団体レベルで出す必要あり。
    • 一度教育を受けさせるだけでは意味がない。医療情報技師のような更新性の資格を作り、補助していくべき

この辺りをもう少し深堀りしてまとめてみたいとは思います。

2015.08.10 JJUG ナイト・セミナー備忘録

jjug.doorkeeper.jp

JJUG ナイト・セミナー 「ビール片手にLT&納涼会」 #jjug - Togetterまとめ

こちらに参加して参りました(・ω・U)
以下メモ

JDK9

www.slideshare.net

元スライドはこちら  
HTML5に対応するのは個人的に助かります。

何故ただの講師である僕がJava EEをやるようになったのか

JavaEEに対する熱い想い
Strutsに対する不安はものすごく同意。 ・JavaEE7もまだまだ英語の方が多し。 ・「日本語の教育がない⇒技術が普及しない⇒教育も売れない」から
「日本語の教育を作る⇒技術の普及⇒教育が売れる」の正の循環に

OpenShiftのある生活 または PaaSのある生活

redhat.slides.com

・社内のサービス作る ⇒ スグに公開できるか? ⇒ あんまりない。  
  なのでモチベーションあがらない。負の循環。
・PaaSがあると ⇒ 作ったものをすぐにデプロイできる ⇒ 開発者もやってみようとなる
・教育も楽になる
・大事な事
    ・生産性
    ・イノベーション
    ・競争力

営業マンだってJavaが好き ~元営業マンがJavaを読めるようになるまで~

・営業マン ⇒ 社交的、トーク上手、プログラミングには縁がない... みたいなイメージ
・営業マンのいいところ
    ・たくさんの人と関係が作れる
    ・数字に強くなる
    ・図を使った表現がうまくなる
・営業マンの悩み
    ・SEの見積もりを信じるしかない

・自分で見積してやればいい

・営業からSEになるために
       ・営業経験を活かせる部分に特化して動く(要件定義、設計...)
       ・システム側のことをひたすら勉強!(応用情報技術者とか)

Javaで最速のハッシュアルゴリズムを求めて

speakerdeck.com

・暗号化アルゴリズムの話 xxHash murmurHash CityHashについて
・ハッシュ関数に求められるもの ⇒ 速さと衝突しなさ  

Excel方眼紙アプリケーションサーバと侍の新機能

www.slideshare.net

・Excel方眼紙 ⇒ めんどくさい!編集大変!
・ExcelにパスとOutputを書いたものをlocalhostに表示させるという荒業を披露。
・jpsでプロセス確認、スレッドダンプ確認、ログを取る ⇒ 侍で一発解決!

聞こえないJavaエンジニアがお願いしたいこと

docs.google.com

・聞こえないと勉強会にいっても講師が何をいっているかわからない。
・キーワードの発音がわからない
・スライドにない事を話されるとわからない。Twitterとかで呟いてほしい
・できるだけスライドに残してほしい
・事前に原稿があるならスライドとは別にアップしてURLを教えてほしい
・手話通訳は、通訳さんがエンジニアでないので、見る側が脳内で補完しないといけない部分が多い。
・そもそもJava用語系は手話表現がまだ定まっていない
・説明はゆっくり話す。図を重視、用語の読み仮名が欲しい

これについては思うところあるので別途ブログに書きます。

Ant「ビルドできません」Travis「よし通れ」

www.slideshare.net

・ある現場で起きたオープンソースのバグのお話
・Travisでコンパイルエラーになるぞ! ⇒ ビルドが壊れている悲しい現実
・issueにしたら阿鼻叫喚
・オープンソースは完璧じゃない(コピペあるし)、でも怖くない
・自分の Pull Requestが通るとやっぱ嬉しいよね

細かすぎて伝わらない、現場で起きた謎現象

・細かすぎてプロジェクトのメンバーには一部の人にしか理解できなかった問題。
・タイムゾーンがAsia/TokyoとJapanが混ざる  
       ・Zoneindoのディレクトリの並び順がバラバラ  
           ・いずれもJSTに変わりはないためスルー
・ActiveMQでCPU100% & 本番環境のみ!  
    ・FullGCで起きると数%に戻る  
        ・強制FullGC発生(1回/時)させるOSGiアプリいれた 
              ・誰か原因解明を手伝ってほしい!

RedPen その後の進捗について

RedPenについて RedPen

PedPenデモ RedPen Demo

www.slideshare.net

WildFly Swarm の紹介

www.slideshare.net

この辺りはほうほうと聞いてるだけになってしまいました(・ω・`U) WildFly使いたい

Java使いがPHP使いにクラスチェンジした話

www.slideshare.net

・ Java使いなのに会社入ったらPHPやってねと言われちゃいました。
・ 型を書かないのが辛い!
・ ==と===ややこしいよ!(PHPあるある)
・ フレームワークは使いましょう
・JPHP使いましょう

犬の私見: JavaのMapとPHP連想配列も違いが大きいのでこのあたりでドハマりしそう。
犬的にはPHP連想配列使うとJavaの配列はめんどい(・ω・`U)。。。

webエンジニアとwebディレクターを兼任してわかった3つのこと

事業側「あのー」エンジニア「今忙しい」⇒ 相互不信が生まれる。お互いによくない ・両方やれて理解できる人間が必要だと感じやってみる

  1. . ディレクターは報われない ⇒ 権限ないけどプレッシャーかかる。エンジニアからなめられる。お金を引っ張ってきてないから評価されない

  2. . データ分析が活かしきれない ⇒ ディレクターはデータ解析で何ができるかわからない。解析チームは事業の課題がわからない。間を埋める人間がいない。

  3. . 失念。。。すいません(・ω・`U)

資料希望(・ω・`U)

疑似乱数生成器の評価

www.slideshare.net

この辺も知らないといけない

Random (Java Platform SE 8)

SecureRandom (Java Platform SE 8)

GuavaのOptional

Google Guava - Wikipedia

Kotlin始めましょう!

Kotlin - Wikipedia

Gradle 2.6の新機能のお話

https://jjug.doorkeeper.jp/events/28182 #jjug · GitHub

Play Framework サポートは結構うれしい

感想

・ 今回は比較的ライトな感じのLT
・ 営業や企画の人もエンジニア側に寄ってきている。エンジニア側も営業や企画を理解するようにしていく必要あり。
・ 技術教育とその発信をうまくコミュニティ、会社内でも回せるようにしていく必要あり
・ 5分の内容をメモしながら聞くのはやっぱ大変(・ω・`U)

謝辞

LTされた皆さま、色々と勉強になることが多く大変為になりました。ありがとうございました。
JJUGの皆さま、本当にお疲れ様でした。ありがとうございました。