White Box技術部

WEB開発のあれこれ(と何か)

【au & DMM】携帯料金9100円から2350円への道

買い換えないと損(?)

iPhone 6sが発売されましたね。販売状況を見てみましたが、都内だと新色以外なら待ちなく買えるようでした。 今回はどこもこんな感じなんでしょうか。

さて、5sを使っている自分は、来月で使用期間が2年になり、キャリアに依存した買い替えタイミングを迎えつつあったのですが、 この「キャリアに依存した買い替えタイミング」がどうにも気に入らなくなってしまったので、今回携帯の契約を見直すことにしました。

というのも、再来月から月々の値引きがなくなるため、古い端末を使っているのに、額面上、新しい端末よりも月々の支払いが多くなるのが、自分の精神衛生上よろしくなかったんです。

というわけで、今日はそんな状況を見直してみたお話です。

高い!とにかく高い!

スマホが・・・高いです・・・

お役所が「安くしろ」と言ったとかは関係なく、月7000円(値引き無し)は、 1サービスに払う額として、ものすごく高額です。

私が大学生の時は高くて月2、3千円だったのが、今や最低がその3倍。 こんな状況なのに、今まで律儀に払っていたことを考えると、まあうまく調教されていたものだと我ながら思います。 私に限ればもういい歳なので、別に払えない額ではないのですが、今自分が学生だったらどうなっていたんでしょうか・・・

ほんの僅かの節約術

私は端末は一括で買い、月々通信費から2000いくらを値引いて貰うスタイルで運用していました。
これは家電量販店で端末購入代のポイントを稼ぐことと、キャリアに借金するような買い方を避けるためです。

それに毎月9000いくらという請求にげんなりする位なら、まだ5000円いかないくらいの請求の方が、 これまた精神衛生的に良かったですし。

電話として使えない電話

5sに変えた時点で無料通話プランもなくなり、たまに数分電話するとプラス1000円くらいされるため、 電話としては極力使うのを避けるようになったiPhoneですが、最近はそんな状況を打破するためか、 通話に適したプランも出てきたようです。

自分達でこういう状況を作っておきながら何を今更、という感じしか私はしませんでしたが、 皆さんはこのサービス展開をどう思ったのでしょうか?私、気になります!

そしてこれの面白いところは、安いだなんだ言いつつ、トータルの料金は上がることですかね。
4sから5sに変わるときでも500円位上がりましたが、今回もそのくらい上がります。安いとは一体何なんでしょうかw

まあiPhone単体でも10万超えてきましたし、何かスマートフォン周りの価格設定だけ色々おかしい気がします。

通信品質向上云々かんぬんは、ぶっちゃけもう求めていないんです。

ということで、次の選択肢、MVNOに登場していただきます。

DMM mobile

mvno.dmm.com

なんかDMMはいろんなことやってますね。艦これで名前を聞くようになるまでは、動画販売の会社だと思ってましたが、3Dプリンタ事業とか英会話とか、 手広く色々やっているようです。1企業でこれだけ多様なサービスを展開しているところは、あまりないんじゃないでしょうか。

気付くとMVNOにも手を出していたようで、後追いになっているからなのか、結構安い価格で展開されていました。 私は毎月大体3.5GBの通信料だったので、以下は全て通信プラン5GB前提で話を進めます。

しかし、この売り文句はなかなかにきてますねw
どこかの「そろそろ反撃してもいいですか?」を思い出してしまいました。

プラン・料金

DMM mobileにはパケット通信のみのデータSIMプランと、通話も可能な通話SIMプランが存在しています。それぞれ5GBの料金は2015/10/25現在、以下のようになっています。

  • データSIMプラン(5GB):1,210円(税抜き)
  • 通話SIMプラン(5GB):1,970円(税抜き)

安い・・・安すぎる・・・

最初はDMMにMNPするつもりだったので、音声通話SIMで契約を考えていたのですが、以下のキャリアのHPと比べて圧倒的にわかりやすい説明ページを見ていて、キャリアメールと留守番電話(11月に追加予定)がないことに気付き、考えを変えました。

mvno.dmm.com

ガラケーと併用するのはどうだろう?

2台持つ鬱陶しさができますが、4sに変えた頃と違って2台持ちの方が圧倒的に安いという現状では、 それくらいは妥協するかなと思った次第です。

ガラケー、もといガラホ()の魅力

魅力は・・・無いです。というより、電話として待受さえしてくれれば良いので、今となっては動作がもっさりしてようが構いません。 というわけで一世代前のSHF31の赤にするつもりでした。デザインもこっちのほうが良かったですし。

http://www.au.kddi.com/mobile/product/featurephone/shf31/www.au.kddi.com

ということで、サクッとiPhone 6sの64GBと、データSIMプラン(5GB)を注文し、どちらも仕事の都合で受け取りは注文から1週間後くらいになってしまいましたが、無事動作することが確認できたので、これで機種変更する準備が整いました。

ここまではすんなり来たんです。そして、ここからが大変でした・・・

auショップ

SHF31は結構古い機種になるため、かなり久しぶりにauショップに行くことにしました。実際、ヨドバシカメラのWEBサイトでは販売終了になっていましたしね。

ヘイト+1

iPhone 6sが使えるようになったので、週末近所のauショップに機種変更に行ったのですが、

「当店に赤は在庫がございません。他店にあるかお調べすることもできません。お客様で調べて頂く必要があります。申し訳ありません。」

まあそういう変なルールがあるなら仕方ないね、と他の店舗に電話してみるも呼び出し音がなるばかりでラチがあかず、その日の機種変更はやめることに。

ヘイト+2

翌日、別のauショップに行くと運良く在庫があったので、契約をお願いしたのですが、

auスマホ交換プログラム | キャンペーン | au

auの公式サイトにはこのようにSHF31を2万円値引きする旨が書かれているのに、「この店舗では2万円分の周辺機器で還元しています」と言われ、予定がいきなり狂ってしまいました。

ややあって、特別に本体価格から引きますと言われたので、釈然としないものを感じつつも契約の話に移ったのですが、そこも一筋縄ではいきませんでした。

ヘイト+3

今回、au電話はただの保険のようなものなので、極力余計な契約は外したいと考えていました。 そこで、パンフレットでは当然のようにプラス連結されているパケット定額の契約が外せないのか確認したところ、

「ここ(パンフレットの※字)に書いてあるように、SHF31ではデータ定額プランが必須となります。」

・・・(゚д゚)ああ、書いてますね・・・

「SHF32にしていただくと外すことは可能です。しかし、これらの携帯電話は中身がAndroidになっておりますので、意図しない通信が発生する可能性があるため、定額プランを追加しておくことをお勧めします。」

(゚Д゚)?ま、まあそういうことも、ある、でしょうけど・・・
あ、でもそれは定額プランの最低価格帯の通信料以下になりますよね?

「回答しかねます。Android側やインストールされたアプリ側の処理になってしましますので・・・」

・・・(;´Д`)インストールされているアプリを全部消してもダメでしょうか?

「プリインストールさせれているアプリは削除できません。」

ガラホ、止めました。

Hate/dawn night ~その日、ガラケーにまた出会う~

3Gのケータイであれば通信が制御できますよとお勧めされたので、3GケータイのGRATINA2にすることにしました。

www.au.kddi.com

もうこの時点でかなりぐったりしていたので、思ったより本体価格が高かったのですが、早く決めて早く帰ろうとしていたところ、 とどめの一撃を貰いました。

「本日から契約が切り替わりますので、今お持ちのiPhone 5sの本日分の通信量が3Gケータイの通信量上限に達していた場合、パケット通信料は上限金額が請求されてしまいます。なお、本日の通信料をお調べすることはできません。」

なんかもうげんなりして、後日来ることにして帰りました。 ちなみに前日の通信料を参考に、通信費の計算をお願いしたところ、20MBだとMAXに到達しているとのことです。 iPhoneの契約で使った通信料なのに、なんともはやでした。

GRATINA2の白ROM購入

機種変更が結局後日になったので、憎しみに濁っていた私は、GRATINA2の新古品(11,800円)をネット通販で買いました。

これ、発売からだいぶ経っているのですが、auショップでは32,400円で販売されており、 そのうえ毎月割は90円(!?)という、かなり減額された額になっていました。

これから機種変更を考える方は、私のように端末を予め自分で買っておく方がお得かと思います。

契約弱者

0時になる前にiPhone 5sのモバイル通信をOFFにしておき、再びauショップに向かい、端末持ち込みでの機種変更をお願いしたところ、今度はだいぶスムーズに進みました。

まあそれでも納得はできなかった契約内容に、

  • iPhone 5sに付いている月々の割引は、今月含め2ヶ月残っているが、今月の割引から消滅する(機種変更当月はiPhoneの料金が値引きされずに請求される)
  • 料金は日割り請求するが、割引を日割りで適用したりはしない
  • 本日の通信料は3Gケータイ側のプランで請求がいく

というようなことがあるのですが、この不平等感は無理やり我慢しました。

auは「森林保護のため、月々の請求を紙で送ることは止めました。請求金額はWebで確認してくださいね。」とか宣って、月々の請求をメール通知すらしないメールサービスを提供している企業なので、とてもロックです。

そして契約へ・・・

これで新しい契約の締結が完了しました。この結果、月々の携帯料金は以下のようになりました。

と、その前に

HP上で展開されている価格は税抜きです。契約してみると当初計算より高く感じるのはこのせいです。8%も取られますしね・・・

8%・・・辛い・・・10%とか・・・どうなってしまうんだろうか・・・

なので、以下では消費税8%を入れた額で表示しています。

忌避すべき電話代(auのみ)

iPhone 6s (64GB)+LTEプラン+必須契約(詳しくはauサイトで)

 ⇒ 合計:税込み 9098円(端末代含む)

これからの電話代(auとDMM)

  • au
    プランEシンプル+EZ WINコース+ユニバーサルサービル料
    743 + 300 + 2 = 1045円
    → 税込み 1129円(8%)

  • DMM mobile:
    シングルデータコース データSIM 5GBプラン+ユニバーサルサービル料
    → 税込み 1308円(8%)

 ⇒ 合計:税込み 2353円(端末代含まず)

というわけで、月6745円の節約に成功しました!

2年間での料金差

月6745円浮くということは、これをauの割引期間である2年間で計算すると、トータルで161,880円浮くことになります。

今回購入した端末代は

  • iPhone 6s (64G):106,704円 (税込、送料込)
  • GRATINA2:11,800円 (税込、送料込)

で、118,504円のため、端末代を考慮しても 161,880 - 118,504 = 43,376円と、約4万円節約できたことになります。

携帯料金を見直してみて

au対応以外はそこまで苦労せずに見直しをかけることができました。 それでこのリターン(年2万円)はそれなりに大きいんじゃないでしょうか?

そして、これで2年間の機種変更圧力ともおさらばです!

端末が壊れたら買うとか、3年単位で買うとか、そういう自由を取り戻した感がすごくあります。見直してよかった!

あとは、SIMフリー端末になったので、Windows Phoneが使いたくなって買った場合や、何かの気まぐれでAndroid端末を使うことになった場合も、SIMを差し替えたり、シェアプランに変更することで対応できるようになったことが、開発者的には大きいかなと思います。

最後に

さて、私がこの言葉を書くのは何気に初めてですが、

本記事に記載されている内容を実施する場合は、 全て自己責任となることを認識して実施してください。

もちろん、個人的にはこの2台持ちプランが現状お奨めで、 DMM mobileに変えて電波に不満が出たということもなく、 むしろauWi-Fiをつかまなくなったので、家を出るたびにWi-Fiオフにしなくて済む分、すごく満足しているのですが、 検証している範囲が都内なので、地域によってはどうなるか不明です。

実家が田舎なので、今度帰省した際にでも電波状況をチェックして追記しようと思います。

2つのHHKB

会社で使っていたキーボードを持ち帰ってきたので、家のキーボードと並べてみました。 上が家の(Type-S)で、下が会社の(無印)です。会社のはだいぶ黄ばんでしまっていますね。

買ったタイミングとしては家の方のがちょうど1年くらい遅いので、無印が5年物、Type-Sが4年物です。キートップ自体は黄ばまないみたいなので、ちょいちょい拭いていれば割と綺麗な状態を維持することができそうですが、フレーム部分はもう置いている場所の影響から逃れられないような気がします。

ちなみに数年打ち比べましたが、私は無印の打ち心地が好きです。音もこっちの方がいいですね。ただ、静かな場所(家とか)だとそれなりにカチャカチャ音が気になるので、そういうところではType-Sの方が集中してコードが書ける気がします。

恐らく会社だと、音が発散しがちなのと周りの音がそれなりなので、無印くらいのキー音がちょうど良いように感じるのかもしれません。

あ、HHKBの方向キーについてですが、私はあればいいな派です。 会社で使っていると他の人が触るときがあるので、その都度解説したり謝ったりするに辟易していますし、方向キーを使うショートカットの操作が少し煩わしいというのが理由です。

とはいえ、自分が使う分にはemacsのキー操作ができれば別段問題ないですね!

お奨めのDIPスイッチ設定

そういえば他ではあまり見ることがないので、需要があるかは謎ですが、HHKBDIPスイッチ設定を晒してみようと思います。こんな感じでWindowsMacで設定を使い分けています。

  • Win:101111
  • Mac:011001

この違いがあるので、併用する場合はちょっと手間です。でもMacBook Proのキーボードを長時間触っていると指先が暑くなって嫌になるので、家ならHHKB使った方が集中できます。 こんな感じでピッタリマウントできますし。

キーボードが家にあるということで

会社辞めました。

今月末の退職なので、正確にはまだ在職しているのですが、有給消化を勝ち取ったので、今週はScalaで遊んだりゴロゴロしたりしていました。来週は実家に帰ったりしようかと思っていたのですが、「来週どこかで出社しろ」とのお達しがあり、ちょっと濁ったりもしていました。なんともですね。

来月から働く会社は決まっているので、転職になるのですが、それを友人・知人に話すと

A「遂に不動のセリが動くのか・・・」
B「本当に決めたのか!」
C「遂にですか」

と、一様に私が転職するする詐欺をしてたかのような反応でした。
確かに自分が残業・休日出勤ばかりなせいで、ゲーム制作をダメにしたりした側面もあるので、転職したいと数年前から言うようになった気はしますが、ここまで同じ反応だと笑うしかなかったです。

転職したいと言い始めた当時は、そうは言いつつも転職する意義を明確に見出せなかったため、現職で頑張って状況を改善させようと奮起していました。そのかいあってか、それなりに要望が通るポジションで仕事をすることができるようになったりと、少しは良くなるところもあったのですが、最終的には、自分の理想と現実の違いを認識するようになり、転職を決意するきっかけになりました。

転職理由

根本的な欲求として、自分が作ったプログラムで誰かに喜んで貰いたい、というのがあるので、これをベースにポジティブな理由、ネガティブな理由を加味した結果、転職することと転職先を決めました。

もちろん現職でも、更に頑張ってあと何年か耐えれば、望む結果に近いものが得られるかもしれませんが、正直いつ死ぬかもわかったものじゃないのに、貴重な時間をわざわざ利率の低い賭けに使うこともない、と思った結果でもあります。

あとFOVEの入金も終わってましたし、FOVEを使ったプログラムを作るために、 いい加減長時間残業の生活から脱出したかったというのもあります。

重なるときは重なるようで

お世話になった人などに退職連絡をしたところ、
「奇遇だな、俺も辞める」「俺も辞めた」「俺も転職する」「俺も」
といった返信をいくつか貰い、話を聞いてみるとネガティブな理由は大体みんな同じで・・・長時間労働の長期間化は良くないですね。

SEからSEへ

というわけで転職するのですが、実は職種的には全く変わりません。次もシステムエンジニアで頑張ります。 変わるのはSIerからWeb屋になることですね。一体どういう感じに変わるんでしょうか・・・不安だ・・・

それに、なんといいますか、大学卒業&就職以来、こうした経歴の変化は初めてなので、不安やら期待やらでドキドキします。同タイミングで転職する先輩が、実は同期、なんてことはないよな・・・というドキドキもあったりしますが、まあそれはそれで面白そうなので、あえて確認していません。

ホント、ドキドキですね!

テストでハマるInvocationTargetExceptionとIE80リケーブルの話

privateメソッドの例外発生テスト

メソッド単位にテストを書いていると、privateメソッド単体の試験をしたくなるときがありますが、 リフレクションを使ってテストした場合は、例外の扱いに気をつける必要があります。

というのも、リフレクション中に例外が発生した場合は、InvocationTargetExceptionに例外が包含されるからです。

例えばあるprivateメソッド中でIllegalArgumentExceptionを発生させるテストを書いたとして、

// ここまでに例外が発生するように事前準備等をしてあると仮定
try {
    // privateメソッドのTestTarget#testMethod(String)の実行
    Method method = TestTarget.class.getDeclaredMethod("testMethod", String.class);
    method.setAccessible(true);
    method.invoke(testSuite, "test parameter");  

    fail("doesn't reach this code.");
} catch (IllegalArgumentException ie) {
    assertEquals("exptected error message", ie.getMessage());   // ←到達しない
}

こんな感じでしょうか。
ですが、このテストは必ず失敗します。invokeが返してくるのがInvocationTargetExceptionだからです。

テストでリフレクションを使ってメソッドに例外を発生させた場合は、getCauseで原因の例外を見る必要があります。

} catch (InvocationTargetException ie) {
    assertThat(ie.getCause(), is(instanceOf(IllegalArgumentException.class)));
    assertEquals("exptected error message", ie.getCause().getMessage());
}

こんな感じですかね。なんか意図通りにいかないなーと思ったときに思い出してもらえると私みたいに頭抱えなくて済むのではないでしょうか!

そもそもテストが必要になるくらいのメソッドがprivateでいいのか、と個人的には思います。 「本当にそれ、privateでいいの?」は、声に出して言いたい日本語であると言って・・・過言ですが、 私のレビューではわりと言ってる気がします。

One more thing...

昨日はWWDCでしたね。後半のMusic推しはだるかったですが、まさか途中でFOBの曲が流れるとは思ってもいませんでした。 FOBはまたライブ行きたいです。が、機会のあることやら・・・

しかし、Developers ConferenceであんなにMusicを推されても、Developerとしてあの場にいた人にとっては微妙かと思いますが、どうなんでしょう?Music APIでも公開されるとかならわかりますが、ただのアプリ紹介でしたしね。

まあおまけですね。Swift 2のOpen SourceとiPadマルチタスクが個人的に熱かったです。

どさくさに紛れて音楽の話をすると、ちょうど前日に愛用しているIE80の端子が接触不良を起こすようになり、 リケーブルを考えていたところ、ちょっと時間ができたのでeイヤホンに物色に行き、 試したUniverse Proがすごくいい感じだったので即決してきました。

www.e-earphone.jp

低音が、素晴らしいです。ベースの音を聴いている感じがすごくします。 欠点を言うなら、シュア掛けしない派にはケーブルについてる癖が邪魔というくらいでしょうか。

ということで、今日シュア掛けしない派から卒業しました。いい音には勝てなかったよ・・・

【Java 8】突然のfor文禁止に泣かないためのlambda練習(文字列長の比較)

for文禁止かlambda禁止か

Java 8を利用することになると、恐らくこの話が出てくるのではないかと思います。 というのもfor文で書くコードは、基本lambdaでも書けるわけで、 そうなるとコーディング規約としてはどちらかに寄せないといけない、みたいなところがあるからですね。

lambdaで書けば並行処理の観点からも有利なので、Java 8を使うのであれば 「(可能な限り)for文禁止」というルールにするのが良いと思うのですが・・・

lambdaは今までのJavaとは考え方を変えないと使えないので、 学習コストやなんやらでプロジェクト内の抵抗に合うことも多いのではないでしょうか。

かく言う私も規約作っているチームに話したら「その場合はlambda禁止ですね」と言われた口ですが。

それなら練習すればいいじゃない(マリー

新しいこと・わからないことはご褒美です!少しずつやっていきましょう。

手始めに、for文を書いていて「これラムダでどう書くんだっけ?」と思った処理をlambdaにしてみます。

文字列長が一番多い文字列を返却する方法

『Listを貰って、その中で一番文字数の多い文字列を返すプログラム』を それぞれfor文とlambdaで書いてみました。

for文の例

以下のfor文では、文字列を順々にチェックしていき、 保持しておいた最大長の文字列を返却することで、要求を実現しています。

public String getMaxStringJava7(List<String> list) {

    String result = "";
    for (String str : list) {
        if (str != null && str.length() >= result.length()) {
            result = str;
        }
    }
    return result;
}
lambdaの例

一方、以下のlambdaでは、リストをStreamに変換し(stream)、その中でnullのものを除外し(filter)、 残った要素を逐次的に文字列長比較して(reduce)、結果を返しています(get)。

なんと処理は1文です(その割には長く見えますが)。

public String getMaxStringJava8(List<String> list) {

    return list
            .stream()
            .filter(str -> str != null)
            .reduce((str1, str2) -> str1.length() >= str2.length() ? str1 : str2)
            .get();
}

気付いてますか?その裏仕様

プログラムを書くと、実現したい仕様以外の処理も書かなければいけないことがあります。

例えばこれらのメソッドに、以下のlistを渡した場合、

List<String> list = Arrays.asList("hoge", "hage", "huga", "foo", "1234", null, "hogehoge", "?");

どちらも"hogehoge"が得られます。

ですが、ここで空のリストや、サイズ0のリストを渡した場合はどうでしょう?

空のリストの場合

getMaxStringJava7とgetMaxStringJava8、どちらもNullPointerExceptionです。 これがいいかどうかはさておき、ここの動作は一緒ですね。 (防ぐのであれば、どちらもnullチェックを処理の先頭に入れればいいですし)

サイズ0のリストの場合

問題はこちらです。getMaxStringJava7はresultの初期値である空文字が返却されますが、 getMaxStringJava8はNoSuchElementExceptionが発生します。

これはOptional#get()の仕様で、呼び出し元のOptional型に値が存在しなければ、 NoSuchElementExceptionが発生するようになっています。

「さあ困った。NoSuchElementExceptionをcatchすれば空文字を返すか? いやいやそれならfor文でいいじゃないか。」

そんな心配は不要です。ちょっとだけさっきのコードを変えてみましょう。

lambdaの例(最終形)

最後のget(値があれば出力)をorElse(値があればそれを返し、ない場合は指定の動作をする)に変更しました。

public String getMaxStringJava8(List<String> list) {

    return list
            .stream()
            .filter(str -> str != null)
            .reduce((str1, str2) -> str1.length() >= str2.length() ? str1 : str2)
            .orElse("");
}

新しいJavaを書こう

実はこれが実現していることはすごくて、 例えば「やっぱりリストが空なら0って文字列を返したい」という場合でも、 最後のorElseを.orElse("0");に書き換えるだけで要求を実現できます。

これがfor文の例だと、『リストサイズをチェックして、0の場合は"0"を返す』という処理を別途書く必要が出てきます。

誤解を恐れずに言うと、少ないコード、見通しの良いコードはそれだけで堅牢です。 プログラマの意思をはっきりとコードから感じることができるため、 他の人によるコード改修時も、バグを生じにさせにくくなる、と信じています。

ただ、やはり学習コストの面では、負の部分も見えますね。 まずはStream関係のメソッドにどんなものがあるかを覚えていかないと、 使いこなしているfor文に逃げたくなる場合もあると思います。

でもこれ、アノテーションによるコーディングができるようになったときも言われましたよね? そしてその結果、アノテーションは禁止されたかというと・・・そんなことはないですよね。 確かに最初は覚えてないので難しく感じますけど、アノテーションを覚えたらコード理解はよくなりませんでした?

だからきっと大丈夫ですよ。lambdaでコードを書いていきましょう!