16/07/12 21:54:41.73 cQbnp1H7.net
>>26
規約も規則もないみたいで好きに作っていいっていわれたからこう作った。
URLリンク(ideone.com)
ちなみにローカル環境でしか動かさないツールだから例外処理はログ出力ぐらいでしか
使わない。
ツールが落ちないようになってるならthrowしちゃいけない理由も特にない。
そうしたらなんでこういう風に作るの?はぁ、ちゃんと見ておけばよかっ、た。
って言われて、レビューとヒアリング聞いてみたの結果これが最適解だった。
コメントは言われたこと少し載せてみた感じ。
URLリンク(ideone.com)
これで伝わる?
多少おかしなとこあったとしてもそんなに意味わかんないことしたのかな。
ややこしい?
ファイル作るのにファイル名抜けてたりなんだりしてるけど黙殺してくださいごめん。
66:デフォルトの名無しさん
16/07/12 22:51:05.48 StomlD/Y.net
う~ん、PG歴2年目くらい?
コードをたくさん書きたいお年頃的な
なんつーかクドい
下のコードで必要十分に見えるよ
>予期せぬ値って何?想定があるの?必要?(笑)
同じ感想でワロタ
67:デフォルトの名無しさん
16/07/12 22:57:14.06 aSzJV8SF.net
普通に書け
普通に
オリジナリティなんていらねえんだよゴミが
68:デフォルトの名無しさん
16/07/12 23:25:13.63 umCvEWis.net
>>55
最後の「ルールの例外」からするとそんな感じだな。
夜はそこまで読んでなかったわ。
>>60,62
大事なことなので?
ってのはさておき、それについても布教用のドキュメントはあるのか?(例>>47)
ググッてもいまいち出てこないんだが。
>>47,48
こんな記述を見つけた。これって何言語か知らないか?
> 言語によっては基本保証やno-fail保証を静的に解析可能なものがあります。
> いくつかの言語ではno-fail保証をそのまま言語レベルでサポートしています。
> コードを静的に解析することでno-fail保証を約束するものもあります。
> また、基本保証を強制している言語や機構があります。
URLリンク(qiita.com)
69:デフォルトの名無しさん
16/07/12 23:28:42.89 VAaNpcds.net
>>66
初心者であるとかお年頃であるとか
そーいうのじゃない可能性もあるな
文章にしたって簡潔に書けない人おるやろ
あの手の人は死んでも直らない
70:デフォルトの名無しさん
16/07/13 00:20:45.58 7t1kL6eB.net
>>68
Eiffelみたいな契約プログラミングによる保証か、
URLリンク(ja.wikipedia.org)契約プログラミング
もしくは、
C++11のnoexceptのような仕組みかな
URLリンク(cpprefjp.github.io)
71:デフォルトの名無しさん
16/07/13 00:26:34.83 C7S+nyqs.net
noexceptでヌルポったらどうなるん?
72:デフォルトの名無しさん
16/07/13 00:44:09.12 yKl3ljrD.net
>>68
>>60のはHaskellのEitherモナドのことを言っていると思われ
URLリンク(itpro.nikkeibp.co.jp)
一応、C++やC#でそれっぽいコードを書いている人はいるみたいだが……
>>71
例外が投げられたら、std::terminate()が呼ばれて終了
73:デフォルトの名無しさん
16/07/13 00:48:21.46 wcqcmuYS.net
>>66
共通の例外処理を繰り返したくないと書かれてるじゃん
読解力がない上に自分の意見を押し付けるってさあ…
74:デフォルトの名無しさん
16/07/13 00:49:32.32 uq0wU9fp.net
>>65
おー書いたか、ご苦労さん。
俺が想定したものとは異なるが、それ以上に情報を含んでいたので、
レビューの様子もよく伝わったぜ。
まあ感想は他の連中と同じだな。
君は難しいコードを書いている。だから駄目なんだよ。
張り切って色々やろうとしているけど、それが駄目なんだ。
手を抜くことには努力を惜しまないってのが優れたプログラマだろ。
少なくともそのレビューと上司はまともだから、言うことを聞いた方がいい。
その上司のコードが何故いいか?それは簡単だから。
構造が単純だから、ぱっと見たらちゃんと動くことが分かる。
それに対して、君のコードはちゃんと動くかはよくよく見ないと分からない。
上司のコードは「自分で処理出来る例外はcatch、それ以外は放置」というポリシーだから、
基本的に下から上がってきた例外は「予想外」として落としている。
つまり例外ツリーは単純なツリー構造で、
このポリシーさえ守れば今後とも簡単に処理を追加出来る。
そして処理も基本的に上から下に処理されるだけだ。単純明快でいい。
対して君のコードは、そうじゃない。
よくよく読まないと果たしてちゃんと動くかどうかも分からない。
そして追加するにしても君が作ったクラスを全部知ってからでないと追加出来ない。
つまり、やることが増えすぎているし、密結合になっている。
対して減らせたのはせいぜいDirectry/Fileの例外の被り部分だけだろ。
それは明らかに設計コストを増してしまっている。
75:デフォルトの名無しさん
16/07/13 00:50:08.11 uq0wU9fp.net
多分勘違いしているのだと思うし、実際そういう奴も多い気もするが、
ベタに書くのが悪いとか、同じようなコードが2箇所に出現するのが悪いとか、
そういう単純な問題ではないんだ。
分かりやすく言えば、
「そのコードを初めて渡されて、ああこのコードはちゃんと動くだろうねと分かるまでに、何秒かかるか」
について最適化しろということなんだよ。
当たり前だが全く同じ内容がダブってたら読むのに2倍かかるから、
それはループなり多態なりして一つに減らせってことになる。
だけど無理に多態したりして「コードを追う手間」が増えるようでは駄目なんだ。
その上司のコードはさらっと読んだだけで動くのが分かる。
でも君のコードはあちこち追い回さないと動くかどうかも分からない。
もちろん君が書いたコードだから、君のコードを君が読むのには苦労しないだろう。
だからもし君に同様の同僚がいて、同様に駄目出しをくらっているのなら、
その時の両方のコードを君が初見で読みこんで、
その構造と動くかどうかを把握するまで何秒かかるかを比較してみればいい。
76:デフォルトの名無しさん
16/07/13 00:53:31.98 2JhFq5Nw.net
>>65
まずMain関数はこれだけだ。
これ以外不要。
public class Test {
public static void Main() {
try {
CreateTempFile("targetPath");
MaggageBox.Show("一時ファイルが作成されました");
} catch(XXXException e) {
MaggageBox.Show(e.Message);
}
}
}
77:デフォルトの名無しさん
16/07/13 00:59:57.51 2JhFq5Nw.net
CreateTempFileの中身はこうだな
void CreateTempFile(string path) {
String directory_path = ディレクトリのパス(path);
Directory.CreateDirectory(directory_path);
File.Create(path);
}
ディレクトリやファイル作成時にExistsなんてやる必要ない。
Existsのチェックした後に、他プロセスから作成されることもある。
「チェック→実行」のパターンはロック機能がない限りたいていアンチパターン。
78:デフォルトの名無しさん
16/07/13 01:03:40.12 2JhFq5Nw.net
結局のところこの程度であればMainに全部入れてもよい良い
public class Test {
public static void Main() {
try {
String path = "targetPath";
String directory_path = ディレクトリのパス(path);
Directory.CreateDirectory(directory_path);
File.Create(path);
MaggageBox.Show("一時ファイルが作成されました");
} catch(XXXException e) {
MaggageBox.Show(e.Message);
}
}
}
このコードを出発点としてだ。
メッセージを変えたいのであれば、
メッセージだけを変えるように工夫すればいい。
Mainに全部入れても良いと言ったが、CreateTempFile()という1関数で実行したいならそれもあり
その場合、CreateTempFile()でメッセージを変えたい例外だけトラップして
メッセージを置き換えて投げ直すだけで、Main関数は>>76のようにシンプルのままでいられる。
79:デフォルトの名無しさん
16/07/13 01:19:00.17 OE4fGXcq.net
なにこのキモいスレw
80:デフォルトの名無しさん
16/07/13 02:08:26.36 uq0wU9fp.net
>>70,72
情報ありがとう。
> 契約プログラミング
考え方はよしとして、大して採用されてないのは効果がいまいちだったのかな?
> noexcept
お?これはなかなか良い感じ。
ついでにそこから辿れる以下も読んだが、こちらも例外を有効活用しようとしている。
(より正確に言えば、例外を有効活用する時のライブラリの作りについてだが)
URLリンク(boostjp.github.io)
例外の文法を使えば、確かに表現力は上がる。それは事実だが、ここに書いてあるように、
当然STLや自前クラスがどの例外保証を持っているかすべて把握してないと駄目だし、
完全活用するとなるとなかなか難しい気がするね。
(プログラミング時に把握しなければいけない項目が増える)
> HaskellのEitherモナド
Haskellの知識はないのでとりあえず日本語部分だけ読んでみたが、
この読み方では有効かどうかは判定不可能だorz
> C++やC#でそれっぽいコード
このURLをくれればすごく助かります。
81:デフォルトの名無しさん
16/07/13 02:16:26.70 2JhFq5Nw.net
> 当然STLや自前クラスがどの例外保証を持っているかすべて把握してないと駄目だし、
例外保証ってなんや?
その例外保証があるかどうかわからんものが
戻り値でエラーを返したら、それを保証してくれると
思う根拠は何や?
気をつけることがあるとしたら、それは戻り値でも同じだし
正常処理とエラーを、一つの戻り値(変数)に入れる分
複雑度は上がるんだぞ。
82:デフォルトの名無しさん
16/07/13 03:23:41.31 vjGvgzcz.net
>>65
ディレクトリを作れない時に、throwして外のスコープに飛ばすのは、ややこしい。
そこでエラー処理できる
外のスコープから見ても、内側からも、throwしてくると考えると、
考える組み合わせ数が増える。
組み合わせ爆発を避けるため、早期に枝切りすべき
また、内外のスコープで、情報を共有するため、
Commonというグローバル変数もどきを、作らざるを得ないから、
内外の関数が、密結合を起こしてしまっている
修正・保守していくうちに、こういうのがいずれ、スパゲティ・泥団子へと成長していき、
誰の手にも負えないようになっていく
83:デフォルトの名無しさん
16/07/13 06:01:23.07 QAw5IbxT.net
>>65
的確な指摘じゃない?
どうみても下の方が出来がいい
84:デフォルトの名無しさん
16/07/13 06:22:04.43 7t1kL6eB.net
>>80
>契約プログラミング
C++だとBoost.Contract
.NetだとSystem.Diagnostics.Contracts
があるね
使ったことないけど
>例外保証
なんか、まじめに考え過ぎな気がする
どのクラスがどの例外保証を持っているかなんて、気にして書いている人なんていないんじゃないか
(と、言うとちゃんとやってる人に怒られそうだが)
例外安全、例外耐性を考慮して、きれいにやるなら把握しているに超したことはないけれど
基本的には「いちいち戻り値でエラー判定するのが面倒。戻り値だとエラー判定忘れることがある(アプリがエラー状態のまま動き続けてしまう)。例外をつかえばそれらを簡単に回避できる」くらいの感覚で使われてるんじゃないかな
例えばオブジェクト指向でクラス設計するときはSOLID原則を意識することはあれ、
そこまで厳密に遵守して書かないし、他人の書いたクラスがSOLID原則に則ってるかなんて気にしないでしょ?
それに今時の言語なら標準ライブラリが例外を投げるから、それらを使うなら自分のコードでも例外を使うことで
「このコードでは、エラーは常に例外で通知する」という一貫性が生まれる
プログラミングにおいて一貫性は重要だ
先日のGoogleのスタイルだと「例外を使わない」という点で一貫性がある
もちろん、現実世界ではそんなにすべてうまくいかないから
必要があれば戻り値のエラー通知を部分的に使うのはかまわないと思うよ
.Netにも例外を投げるInt32.Perseと投げないInt32.TryPersreの2種類があるし
>Either
"C++ Either"や"C# Either"でググれば「書いてみた」系のブログが引っかかる
85:デフォルトの名無しさん
16/07/13 07:23:43.92 L2fL/y00.net
おはようございます!
ご回答ありがとうごさいました。
そうかー難しいのか。
難しいということはたまに言われますが、なにが難しいのかわからなくていつも悩んでいるので、自分は設計には向いていないのかもしれません。
下流で頑張ります。
皆さんも今日一日頑張ってください!
それでは!
86:デフォルトの名無しさん
16/07/13 09:37:32.17 2JhFq5Nw.net
>>84
> .Netにも例外を投げるInt32.Perseと投げないInt32.TryPersreの2種類があるし
名前が重要なんだよ。(ちなみにParseな)
例外を使ったときのメリットは、関数の名前通りの戻り値にできるってこと。
Parseはパースするんだよ。だから戻り値はパースした結果であり
エラーを戻すことはない。パースできなければ例外。
TryParseはパースすることをトライするんだよ。だから戻り値はトライした結果。
もしトライすることすらできなければ、それは当然例外。
その2つは、例外を投げるかどうかの違いじゃなくてやる処理の違い。
そしてどちらもやるべきことができなければ、例外を返す。
87:デフォルトの名無しさん
16/07/13 19:05:13.08 OE4fGXcq.net
そんなに力説するほどの事か?w
88:デフォルトの名無しさん
16/07/13 21:38:19.72 2JhFq5Nw.net
>>87
これは力説するほどのことだよ。
なぜなら可読性の話だから。
英語わからんとか、ソースコードを命令の並びだとかしか
認識してないレベルの人にはわからないだろうけど、
ソースコードは読むもの。
読みやすさを大きく左右する要素の一つが、
適切な名前をつけているかどうかだから。
たまに適当な関数名つけてる人がいるけど、ほんとやめてほしい。
適当な単語を並べただけじゃソースコード読めないから。
名前から意味がわからないから、中の処理を読んで解析しないといけなくなる。
89:デフォルトの名無しさん
16/07/13 21:54:55.05 OE4fGXcq.net
それなら問うが
Parseが返すパーズした結果とは何ぞや?
TryParseが返すトライした結果とは何ぞや?
俺には名前だけではさっぱり分からんのだが
これがお前の望む適切な名前とはとても思えんのだがw
90:デフォルトの名無しさん
16/07/13 22:01:55.88 lnUCd6s/.net
>>89
友情努力勝利に決まってるだろ
91:デフォルトの名無しさん
16/07/13 22:31:57.93 oLxbX2RO.net
正直TryParseで変換できちゃうのはちょっと気持ち悪い
92:デフォルトの名無しさん
16/07/13 22:44:01.74 uq0wU9fp.net
>>84
例外をエラー通知として使う分にはその辺は知らなくていいんだよ。
ただ、例外で復旧させようとするのなら、その辺を全て把握する必要がある。
そして彼等はそれにも耐えられるようにSTLを整備しようとしている。
それは無駄なコストを発生するから、それについて彼等も議論しているわけだ。
ただ、今見た限りはまだ環境が追いついていないね。(ドキュメントが出来ていない)
偶々このページを見ていただけだから、unordered_map自体に意味はないけど、
URLリンク(en.cppreference.com)
個々のメソッドには例外発生時の動作が書いてあるけど、本体のページに纏まっていない。
だからunordered_mapを使ったらどの例外安全になるのかを確認する為には、
全部のメソッドを確認するしかない。
大半の奴は確認もせずに「例外を使った方が安全です」と信じているだけだろう。
例外を活用しようとなると、既に書いたように、大ジャンプを避けられない。
その場でいちいち判定するだけなら、余計に汚らしくなるだけだ。
ただしこれについては速度面ではtry/catchの方が上だと指摘されているし、
表面上のコード量では確かにそうだ。
とはいえ、x86に於いては分岐予測+投機実行なので、
ほぼ常に通らないパスのif-elseifについては、
気になるのなら1段目で切ってしまえば速度低下はしない。(if (result>0))
93:デフォルトの名無しさん
16/07/13 22:44:36.15 uq0wU9fp.net
> 必要があれば戻り値のエラー通知を部分的に使うのはかまわないと思うよ
個人的にはTryParseをよく使っている。それで十分だから。
必要性はない。try/catchでも書ける。
戻り値判定の場合は、その場での処理が強要される。
結果、65の上司型のコードしか書けない。
実際にあのコードを戻り値判定に変換するのも簡単だ。
この使い方をする場合は好みの問題でしかない。
一方、例外を用いれば、65がやろうとした「積極的にthrowして統合的に扱う」ことも出来る。
戻り値判定でこれをするのは大変なことになるので、これをしてこそ活用だと言える。
とはいえ、これがろくな事になる気配が全く感じられない。
ちなみに、言語的な例外復旧能力に必ずしも頼る必要はない。
上位レベルでの復旧も実は簡単だからだ。
例えばTryParse、ファイルから読むのならソースは保持する必要がない。
Seek出来ないネットワークストリーム等なら、MemoryStreamに一旦受ければいい。
JSONみたいに階層ありオブジェクトを丸々生成するのなら、成功した後に差し替えればいい。
これらの場合は、ロールバックを上位で行うことはほぼ自然に出来てしまうので、
結果的にSTLが実装した例外機構の為に無駄に税金を払う事にしかならない。
この点を修正しようというnoexceptはC++っぽくていいが、
なるほどこんな事をやっているうちは生Cを駆逐することは出来ないだろう。
94:デフォルトの名無しさん
16/07/13 22:45:05.83 uq0wU9fp.net
生Cはある意味世界がno-fail保証されている。
そして失敗した場合は上記のように自前で戻すか、諦めるしかない。単純な話だ。
ロールバックする気なら、この点については例外で処理した方がコード的には楽だ。
しかし実行効率ではどうやっても生Cの方が上になる。何もしてないコードだからだ。
生Cは世界が単純に出来ている。あまり気にしたことはないが、これは大きな利点だね。
言語がシンプルな結果、シンプルな記述を強要され、結果的に65のようなコードを記述出来ない。
65みたいな「考えすぎておかしくなっている奴」には生Cギプスが効くかもしれない。
> .NetだとSystem.Diagnostics.Contracts
以下を見る限り、型についてのTDDみたいな感じだな。
静的チェックが出来るのはいいね。ただ、流行るかと言われれば微妙かな。
URLリンク(visualstudiogallery.msdn.microsoft.com)
> C++ Either
以下でいいか?
URLリンク(faithandbrave.hateblo.jp)
つまりは例外を呼ばずに値として埋め込みたいだけか。
関数型で組んだ場合には個々の要素で例外呼ばれても困るから、そりゃこうなるだろう。
そういった意味ではC++の例外機構は「手続き型」にしか対応してないね。
そこですぐ呼ばれる前提だ。
他の関数型言語の例外機構ってどうなっているんだ?知ってたらよろしく。
Haskellがこの手で値埋め込み、後でユーザ側で確認するというのは分かった。
なおJavaScriptは0割は無限大になるというお気楽仕様だ。
当初は驚いたが、正直これで問題ないよなとも思う。
95:デフォルトの名無しさん
16/07/13 22:58:10.35 2JhFq5Nw.net
>>89
> Parseが返すパーズした結果とは何ぞや?
正しくはInt32.Parseなんだから当然Int32だろw
Int32に変換した結果を戻す
(変換できなければ戻さない)
> 俺には名前だけではさっぱり分からんのだが
あー、うん。クラス名が先に作ってことに
気づかなかったのねw
>>86で引用してる>>84にかいてあんだろ。
気づけよw
96:デフォルトの名無しさん
16/07/13 23:09:44.65 jyyAd6hv.net
Int32.Parse だからといって、必ずInt32が返るとは限らないだろ
おまえは、human.age()で必ずhumanが返ると考えるか?
97:デフォルトの名無しさん
16/07/13 23:11:23.52 2JhFq5Nw.net
>>94
> なおJavaScriptは0割は無限大になるというお気楽仕様だ。
いや、お前、例外っていったら0除算しか思いつかんのかよw
eval("{") とか実行してみろ。JavaScriptは例外を使う言語だ。
0以外の数値を0で割ったら無限大になるのは数学的に正しい。
JavaScriptが無限大を扱える言語ってだけだ。
もちろん数学的に正しいことをやっているから、 0 / 0 は NaN (非数)になる。
少なくともこの点は、お気楽ではなく高度な言語だと言える。
もっともJavaScriptに例外が搭載されたのはJavaScript 1.4(1999年あたり)からだけどな。
それ以前は(エラーを戻り値で返すのではなく)スクリプトが停止され
window.onerrorイベントが呼ばれたんだっけな?もう忘れたが。
98:デフォルトの名無しさん
16/07/13 23:11:30.03 jyyAd6hv.net
いっとくが、human.age()で必ずintが返るとは限らないからな
もしかしたらageオブジェクトが返るかもしれないからな
99:デフォルトの名無しさん
16/07/13 23:12:49.31 2JhFq5Nw.net
>>96
> Int32.Parse だからといって、必ずInt32が返るとは限らないだろ
> おまえは、human.age()で必ずhumanが返ると考えるか?
Parseとageで関数名が違ってるじゃんw
名前で返すものが決まるって言ってんだろ。
human.parseだったら、human返すんじゃねーの?
100:デフォルトの名無しさん
16/07/13 23:13:53.29 jyyAd6hv.net
>human.parseだったら、human返すんじゃねーの?
そんなの思い込みだろ
ヒューマンパーズオブジェクトが返るかもしれないだろ
101:デフォルトの名無しさん
16/07/13 23:18:25.58 2JhFq5Nw.net
>>94
> 他の関数型言語の例外機構ってどうなっているんだ?知ってたらよろしく。
関数型で戻り値でエラー情報なんか返したら
大混乱になるわw
関数呼び出しの中の、関数呼び出しの中の、関数呼び出しの中の、関数呼び出し で
エラー情報が返ってきたら、if式による分岐の嵐でもはや
関数型言語のように見えないだろうね。
102:デフォルトの名無しさん
16/07/13 23:22:40.62 2JhFq5Nw.net
>>100
> ヒューマンパーズオブジェクトが返るかもしれないだろ
ほらね? 何が返るか想像できてるじゃんw
Int32.Parseじゃ何を返すかさっぱりわからないって言ってるから
それが間違いだよって話。
なにも100%完全に返り値の情報がわかるなんて言ってないんだよw
103:デフォルトの名無しさん
16/07/13 23:36:52.14 C7S+nyqs.net
型を見りゃいいだろ
まさかこのスレに居ながら、屁臭いペチプ~やゴミのペールやペールの糞からひり出されたルビーや・・・そんな糞まみれのウンコ野郎はおるまいね?
104:デフォルトの名無しさん
16/07/14 00:31:59.76 4Ps/X1K6.net
>>102
いやお前それ苦しいだろ
>ほらね? 何が返るか想像できてるじゃんw
想像?
思い込みでしょ
ヒューマンパーズオブジェクトが返るかもしれない、とは書いたが
実際には何が返るかわからないから、そう書いただけであって
どうせ、仕様を調べなきゃならないんだよ
105:デフォルトの名無しさん
16/07/14 01:02:32.63 9qkjMq+e.net
>>104
言うと思ったw
でお前これから先仕様なんて調べるの?
調べないよね。もう覚えてしまったから。
あとは文字を見れば思い出すはずだ。
適切な名前があると覚やすいっていうのはこういうこと。
106:デフォルトの名無しさん
16/07/14 01:31:15.59 rhZMoeJF.net
>>101
>関数型で戻り値でエラー情報なんか返したら
>エラー情報が返ってきたら、if式による分岐の嵐でもはや
ifの分岐しないためにfunctorだのアプリカティブだのmonadだのtraverseがあるじゃん?
try1 >=> try2 >=> try3 >=> ... tryN
みたいので「成功するまで処理を続けて失敗したら例外情報をもって途中で抜ける関数」を作れるし
こういう合成力は関数型の強み
107:デフォルトの名無しさん
16/07/14 06:27:39.21 cfi8dg7p.net
自分の思い込みの通りなら良い設計良いコードw
108:デフォルトの名無しさん
16/07/14 07:26:28.53 xgZTwt3g.net
正しく意図した通りに騙してくれるなら
明らかに良いコードだろ
頭のてっぺんからケツのシワまで数え上げてようやく読解できるコードが糞じゃなきゃ何なんだ
109:デフォルトの名無しさん
16/07/14 07:44:38.40 cfi8dg7p.net
クソの主観によりクソ認定されたコード達w
本当は良い奴も沢山いただろうに不憫だわーw
110:デフォルトの名無しさん
16/07/14 08:31:57.85 qme/E7bl.net
車輪の再発明しか出来ない人がいると聞いて。
111:デフォルトの名無しさん
16/07/15 23:14:34.82 /IkQTUfk.net
DAO とかDTO ってのが出てくるアーキテクチャは手続き型であって、オブジェクト指向ではない
ってのが解る人ここにいるか?
112:デフォルトの名無しさん
16/07/15 23:20:25.90 sS/v2c9e.net
そんな嘘ついちゃいけないんだお
113:デフォルトの名無しさん
16/07/15 23:39:15.88 iR/HdeCl.net
今の日本人は>>111みたいな馬鹿が普通なんだお