はてなキーワード: 引数とは
俺は設計より実装の方が苦手だわ。プログラミング言語の特に脈絡のない仕様(ファイルオープンして1行読むのってどうやるんだっけ?改行コードの扱いはどういう仕様だっけ?EOF判定はどういう関数だっけ?str2numに対応する処理の関数はなんだっけ?文字コードがUTF8じゃない場合にはなんか特別な引数書かないといけないんだっけ?1行読んでポインタを先頭に戻したい場合はどう書くんだっけ?ていうかディレクトリ内のファイルリスト取得する関数はなんだっけ?あー余計なファイルをはじくための正規表現の仕様はなんだっけ?.......)が全く記憶できなくてすげーストレス。なんど覚えても雑然としすぎていてすぐ忘れる。ファイル云々に限らずプログラミングは一事が万事全部そうだし…。
Steamで買った『Recursed』というゲームを全ステージクリアしたので、記念に感想を書く。
Steam:Recursed
https://store.steampowered.com/app/497780/Recursed/?l=japanese
一見すると『Recursed』は2Dのレトロな雰囲気のアクションゲームである。操作はシンプルで、方向キーで左右に移動し、アクションはジャンプと物をつかむ/投げるだけだからだ。部屋の中を移動してブロックをつかんで足場を作ったり、鍵をつかんで扉を開錠したりしてゴールへと到着(crystalを獲得)すればステージクリアだ。
ステージの始めはチュートリアルの様に簡単だが、ステージを経るごとに難しくなり、そのうち何度も試行錯誤したり難しさのあまり何十分も頭を抱えたりもした。
この複雑さを生み出す要因は箱(ゲーム中表記ではChest)である。このゲームでは箱の中へジャンプすることで部屋の内に入れるが、一度箱の外にでると箱の内部状態はリセットされてしまうのだ。よって箱の中にブロックや鍵などのオブジェクトを持ち込んでも保存することはできないし、ブロックの位置もリセットされるし、開錠した扉もまた施錠されてしまうことになる。
さらに大きな特徴として、箱を持ち歩いて移動することができるのだ。それにより、箱を持ったまま別の箱に入ったり箱を持って箱の外にでることもできる。
そして、ステージを経ると箱の中の部屋は箱の外と同じ部屋という場面に出くわす。Recursedは『再帰呼び出し』という意味らしいが、まさにこのゲームのタイトル通りの現象が起こるのだ。そして、以降のステージでは再帰を交えることでパズルの複雑さはより深まっていく。
再帰は数学的帰納法やアルゴリズムでは定番の概念だが、それがパズルとなってプレイヤーの思考回路を奪ってくる。私はかつて社畜プログラマとしてJavaプログラミングを経験していたので、箱に入ることはメソッドを呼び出すことの様に感じた。オブジェクトを持って箱に入ることは引数を使ってメソッドを実行することであり、オブジェクトを持って箱の外に出ることはreturn文でメソッドを終わらせることであった。
「ゴール前の段差が大きくブロックが必要だから、ブロック生成メソッドを呼び出してブロックオブジェクトを返り値として渡さなくてはいけないけど、そうすると鍵オブジェクトをゴールメソッドの引数として渡すことができなくて……、いっそのこと、ブロックメソッド内からゴールメソッドを呼び出すべきか……、メソッドの返り値は一つだけだが何度も呼び出せばいけるか? この緑色のオーラはなんだ? Staticを意味するのか? Staticなオブジェクトの位置情報をあらかじめ変更しておけば、ゴールメソッドで引数渡しをする必要がなくなるのか?」
こんなことを一つのステージをクリアするだけのために何十分も考えていたのだ。念のために書いておくが、ゲーム内には数学用語やプログラミング用語は一切出てこない。ただ単に、私にJavaプログラミングの経験があるからその用語でパズルを考えていただけだ。ゲーム内で箱から出入りしたりオブジェクトを箱の中から出し入れするとどうなるかを、Eclipseでステップ実行するように想起していた。ちなみに、ゲーム内で存在しない部屋や壁の中に移動しようとするとparadoxが発生して強制的に特殊な部屋へ移動されるが、私はその度にステップ実行でExceptionに遷移されたことの様に感じた。他の言語に精通するプログラマだったり数学畑の人ならば、私とは異なる概念でパズルを思考をするのだろうか。
プログラマを辞めて何年もプログラミング的思考をしてこなかった私でも全ステージクリアすることができたのだから、学校でプログラムを学んでいたり現役でプログラミングをしてきた人ならばこのゲーム『Recursed』をクリアすることは可能だろう。いっそのこと、『Recursed』のクリアすらできない人にプログラミングができるのか? と煽ってみたいくらいだ。
ちなみに、もし私が社畜プログラマ時代にこのゲームをやったらブチ切れていただろう。なんで仕事でプログラミングで脳を酷使した上に自宅のゲームでも同じようなプログラム的な思考をしなければならないんだよと。プログラミングから何年も離れていた今の私にとって『Recursed』は、プログラミングや単体テストが無事成功した時の快楽を思い出させるものだった。
『Recursed』はパズルとしての難易度は非常に高いが、理不尽な解法を求められることはない。理不尽な解法のクイズやパズルには怒りが湧いてくる。ひと昔前のクイズ番組を見たことのある人なら『モヤッとボール』を投げつけたくなる、と言えばその感情が伝わるだろう。『Recursed』はどんなに難しいステージでも、ただただ開発者のパズル作成能力に感嘆するだけで怒りは湧いてこない。
似たようなアクション風パズルゲームとして有名なのは『The Witness』であろう。『The Witness』も私が好きなパズルゲームであり、ゲームとして高い評価を得ていることに間違いはないのだが、しばしば理不尽な解法を求められるパズルがありその度に私は怒りが湧いてきたものだ。そう考えると、『Recursed』はパズルとしての洗練さだけなら『The Witness』を超えるものだと私は思う。
具体的にパズルを解説するととただのネタバレになってしまうので(もっとも、文字だけでパズルの解法を説明できないのだが)、『Recursed』で私が好きなステージを述べる。順番は攻略順に並べた。
チュートリアルの様に簡単だったこれまでのステージから突如再帰の概念を見せつけられることで、このゲームのタイトル名の意味を理解することになった。
鍵を手に入れたら扉に到達できず、先に扉に到達したら鍵が手に入らずで、まさにインターロックの名前に相応しいステージだった。
一画面だけのオブジェクトが少ないシンプルなステージだが、氷の壁に阻まれてゴールできず苦戦した。試行錯誤の繰り返しの末クリアできたが、何故クリアできたのかがわからない。
The Voidのステージはどれもこれまでの集大成という感じでやりごたえあったが、中でも頭をひねらせたのがこれ。ゴールの部屋を水没させたり水の無い状態で入ったりして鍵を運搬するのに苦労した。
箱を左右へ投げて移動を繰り返して、高い位置にあるゴールを目指すのがまさにEscalateというステージ名そのものだった。paradoxを発生した後のパターンが複雑だったのが印象に残っている。paradoxを発生させたらcrystal獲得(通常のクリア)できないのかよ……という落胆は大きかった。しかし、それだけにcrystal獲得とdiamond獲得(paradox発生によるクリア)のどちらも大きな達成感を得られた。
簡単そうに見えて難しく、唯一ステージを飛ばして次のステージへと進んだので印象に残っている。後に複数日に及ぶ数時間の試行錯誤で改めてこのステージをクリアができて、クリアにかかった時間が最も長くなったステージでもある。しかしながら、おそらく開発者の想定外の方法でのクリアであり。初期画面から右の方へ一切行かずにOobleckさえ使用しないというクリア方法にスッキリしなかった。といっても、開発者の想定を無視するゴリ押し的なクリアを見つけたのはこのステージだけだった。
The Void/Escalateと似たコンセプトのステージだが、釜(JavaにおけるThread?)のギミックを利用したより複雑な構成となっている。高い位置にあるゴールを目指すのは、やはりFlightというステージ名そのものだった。
この記事を投稿する前にエンディングを見れていないことに気づいた。
全ステージクリア(全てのCrystal取得)したからと、この記事を執筆するためにネタバレを気にせず攻略情報を調べていたけど、エンディングなんてわかる訳ねえよ。The Void/Trilemmaの最後にCrystal取得とは関係ない意味深なオブジェクトがあることには気づいていたけど……。ちなみに、私のSteam実績によるとdiamondとrubieの全取得はできてないけれども、もう取得する気力はない。パズルゲームガチ勢にとっては、実績全解除を目指さない私は軟弱者に映るのだろうか? 攻略を調べずに実績全解除できる人は、高い論理的思考能力を有しているに違いない。
GoMockってのはGo言語のライブラリで、依存するinterfaceをテスト用モックに置き換えてくれる。
それで、テスト中のモックの期待される振る舞い等を簡単に定義できるのだ。
期待される振る舞いってのは、モックのメソッド呼び出しやその引数とかだな。
期待される呼び出しが無かったり、引数が違ったりするとテストが失敗してくれる。
非同期処理のテストだとよく、wg.Done()をモックにさせたりする。
けれどそのうち辛くなってくる。
つまり、たくさんのinterfaceに依存するサービスオブジェクトのメソッドをテストしようとすると、たくさんのモックのたくさんのメソッド呼び出しの全部の期待される振る舞いを書かないといけない。
モックのメソッドの戻り値によってサービスオブジェクトのメソッド内の挙動が変わる。
すると連鎖的に、メソッド内で続いて呼ばれるモックに期待される挙動も、変わる。
依存interfaceが増えるとこの場合分けが指数関数的に増える。
当然だ。
Go言語にはテーブルドリブンテストっていう、テストケースは配列に簡単にまとめられると良い、という慣習・哲学がある。
しかし俺のサービスオブジェクトはテストケースが肥大化複雑化しすぎてしまったようだ。
モックの期待される挙動を細かくケースに分類して配列にするのは恐ろしく辛い作業だ。
やりたくない。
どうしてこうなったかは明らかだ。
モノシリックで巨大で複雑なものは凡人には扱えないからやめとけ、と偉い人は言う。
やったよ(見様見真似で)。
でもじつはここはまだ山麓だったのです。
分け入っても分け入っても青い山。
おれはどこに行けばいいのだ。
参考文献
https://little-hands.hatenablog.com/entry/2020/12/22/ddd-in-first-3month
function hoge(callable $f = fn ($a) => $a) {} // エラー
function hoge(callable $f = 'intval') {} // エラー
function hoge(callable $f = null) {} // 合法
即時関数くらい書かせろよなぁ。せめて文字列でcallableな関数指定できるようにしてほしいわ
省略するには、$fがnullか確認してコールバック実行時にif文だか三項演算子だかで切り分けるしかない
なんで callable型 に null 入れられんだよ。キメェなぁ。なんでデフォルト値として関数代入できねーんだよ。使えねぇなぁ
いかにも増築増築で別々の機能を後付けて盛り付けてるって感じで、機能間の生合成がいまいちなんだよなぁPHP
まあ呼び出し元では hoge(fn ($a) => $a) みたいな呼び出しできるので、マシっちゃマシだけど
参考:
https://stackoverflow.com/questions/55587939/default-callable-in-function-definition-in-php-7
プログラマーに憧れる皆さん!こんばんは。
「自分は文系だから」「未経験だから」と諦めていませんか?大丈夫です!プログラミングにセンスは不要です。正しい手順で学べば、文系や未経験でも、誰でも一流のプログラマとして活躍することができます。
今日は、未経験から最短でWeb系企業に就職するための勉強法をご紹介します!
もっともオススメの方法は、顕正会のセミナーに参加することです。
顕正会は、日本で最大のエンジニアのコミュニティであり、非常に良質なテキストを用いて、プログラミング初心者向けのセミナーをしていることで有名です。顕正会に入ることで、未経験からでも一流エンジニアのノウハウを学ぶことができます。
また、意外と知られていませんが、日本のエンジニアの8割は顕正会の出身です。実はあのひろゆきやビル・ゲイツも顕正会の出身です。ですので、顕正会のネットワークを介して就職先を斡旋してくれたりしますし、自分が顕正会員だと、面接時にも非常に有利になります。
顕正会のセミナーは、インターネットからも応募することができますし、秋葉原などで声をかけられることもありますので、誰でも簡単に参加できます。会員もフレンドリーな方ばかりですので、是非、お気軽に応募してみて下さい!無料体験もできますよ。
プログラミングの勉強を始める前に、まず、必要なものを準備しましょう。必ず必要なものと、できればあると良いものは以下の通りです。
可能な限りスペックの高いものを買いましょう。2021年現在であれば、CPUは18コア、36スレッド。RAMは128GBくらいはあると良いでしょう。ストレージはSSDであれば1TBもあれば十分です。
OSは、Windowsで開発するならWindowsが、Macで開発するならMacが必要です。よく分からなければMacを買っておく方が良いでしょう。基本的にMacにできてWindowsにできないことはありません。
インターネットは、この記事を見ている人は既に持っているでしょう。ただし、モバイル回線で見ている人は、自宅に有線のインターネット環境を用意した方が良いです。
顕正会に入会すれば、上記のスペックのPCを無料で貸し出ししてくれます。また、法人向けの専用線を無料で取付工事を行ってくれる上に、通信費を全て負担してくれます。
まず、他の会員と連絡を取るために、SNSのアカウントを持っていると良いでしょう。
最近は完全にPC上での学習もできますが、やはり、勉強の基本は紙のノートに直接書くことです。医学的にも、手指の動きと脳の記憶回路が関連していることは証明されており、手を動かすことで効率的にものを覚えることができます。
Kindleなどの電子書籍リーダーは持っておいた方が良いです。紙の本は時代遅れです。いやしくもITのプロを目指そうという人間が、このような最先端のデバイスを使っていないのは恥だと思うべきです。紙の本を買わないことは、環境を守ることにも繋がります。現金も持つのはやめましょう。
せっかくセミナーに参加しても、受身で聴くだけでは、プログラミングを習得することは難しいです。ここでは、自宅でどのような勉強をすればよいのか、ご紹介します。
まずは、教科書や参考書を写経することから始めましょう。教科書や参考書の本文を一字一句正確に書き写すのです。
よく、「写経は理屈を学べないからだめだ」と批判されますが、まずは正しい「型」を体に覚え込ませるのが先です。野球や水泳などでも、細かい理屈よりも先にフォームを固めるのと同じです。書き写している内に理屈は自然と身に付きます。
また、写経のメリットは「飛ばし読み」を防げるところです。一字一句正確に写経をすれば、細かい部分を「分かったつもり」になって飛ばしてしまうことを防げます。たとえば、比較演算子の等号は=ではなくて、==です。プログラミングはこういうところに注意して学ばなければいけません。
教科書のサンプルコードをノートに書き写したら、それを今度は自力でフローチャート(UML)に変換してみましょう。そうすることで、自分が本当にそのコードを理解しているのか、確かめることができます。
フローチャートやUMLが素早く正確に描けることは、プログラマーとして働く上で非常に重要なスキルです。それらはソフトウェア設計の基礎となりますし、ソースコードを読めない営業や顧客にとっては貴重な資料となるからです。プロのエンジニアは、COBOLのソースコード10万行を1週間でフローチャートにして、Excelに転載することができます。
ここで一つ注意すべきことがあります。フローチャートを描くときは、必ず専用の定規を用いて描いて下さい。フリーハンドで描いたものは業務ではフローチャートとは認められません。これはまともな企業に就職すれば研修などで必ず習うことですから、今の内に覚えておきましょう。
エンジニアを目指すのであれば、プログラミングだけではなく、Excelの使い方も学びましょう。Excelはエンジニアにとっての万能プラットフォームです。エンジニアはあらゆる作業をExcelで行います。セル結合や罫線を用いて、見栄えの良い資料を作る技術は、エンジニアにとって必須です。
プログラミング学習中であれば、たとえば以下のような題材の資料を作ってみると良いでしょう。
尤も、以上の資料は、ツールを使うことで自動で作成することもできます。たとえば、ソースコードの更新履歴はGitなどのバージョン管理システムを使うことでも管理できます。しかし、それらの資料としてのクオリティは非常に低いため、アマチュアしか使うことはありません。プロを目指す皆さんは、必ずExcelを使いこなせるようになりましょう!VBAの習得も必須です。
以上、プログラミングの勉強法について解説しました。ここからは、実際にソースコードを書くときのコツを紹介していきます。他のプログラマと差をつけることができる技術ですので、意識するようにして下さい。
理想は、aやxなどの一文字です。ただし、これだけだと26文字しか使えないので、a1, a2, ...のように連番でグルーピングすると良いです。
また、変数の宣言と使用箇所が離れた場合に、変数の型がすぐに分かるように、たとえばint型であればi1, i2, ...、string型であればs1, s2, ...のように命名すると、読む人に親切で自分もミスしにくくなります。
変数名を長くするのは、以下のデメリットがあるため、絶対にやめましょう。
多くのプログラミング言語には、クラスや関数といった機能がありますが、これらは基本的にライブラリ提供者などが使う想定の機能であり、一般のプログラマが使うのは好ましくありません。したがって、クラスや関数はなるべく使わないようにして下さい。
不要な関数を作らないためのテクニックには、以下のようなものがあります。
まず、関数の引数に「フラグ」を渡し、関数内部で処理を切り替えれば、1つの関数で複数の処理をすることができます。
function f(i) { switch(i) { case 1: // i = 1のときの処理 break; case 2: // i = 2のときの処理 break; case 3: // i = 3のときの処理 break; // ... } }
この方法は、以下に述べる「変数の寿命を伸ばす」効果もあります。つまり、この関数内で宣言された変数は、すべての処理で共通して使用することができます。
クラスに不要な関数を作らないようにするには、「継承」を用います。複数のクラスで用いる関数を定義したクラスを1つ作っておき、そのクラスを継承すれば、新しいクラスに関数を定義する必要はありません。
理想的には、プログラム内のすべての関数を同一のクラスに定義し、それを継承するべきです。そのようなクラスは俗に「神」と呼ばれ、プログラマからはこの上なく尊ばれています。
class God { f1() { // 関数1 } f2() { // 関数2 } // ... } class C1 extends God { // 何も書かなくても上の関数が使える! } class C2 extends God { // 何も書かなくても上の関数が使える! } // ...
変数は宣言する場所によって、ソースコードのどの範囲から参照できるかが決まっています。この範囲が広いことを、「変数の寿命が長い」と言います。
たとえば、以下のコードのaは、関数定義の外側からは参照することができません。
function f() { var a = 1; return a; }
一方、以下のコードのaは関数の内外どちらからでも参照することができます。
var a = 1; function f() { a = 2; return a; }
せっかく作った変数がすぐに死んでしまうのは、非常にもったいないです。ソースコードの表面には現れませんが、変数を作ったり捨てたりするのには、計算コストがかかります。したがって、寿命の短い変数を作りすぎてしまうと、プログラムが遅くなってしまいます。
また、変数の寿命が長いということは、変数をたくさん作らなくても、1つの変数を色々なところで利用できるということであり、とても便利です。たとえば、上記の前者のコードでは、関数の外部からaの値を参照したくなっても、参照することができません。後者のように書いておけば、プログラムのどの箇所からでも、aの値を参照したり、更新することができます。したがって、変数の寿命を長くするとプログラムを変更しやすくなります。つまり、保守性が上がります。
例外とは、プログラムが予期しない処理をしようとした場合に、プログラムの実行を停止し、呼び出し元にエラーを通知する機能です。たとえば、「test.txt」というファイルを開こうとしても、そのファイルが存在しない場合は、例外となります。
例外が発生すると、プログラムが停止してしまうため、非常に困ります。したがって、プログラマは例外をきちんと処理しなければなりません。
ほとんどのプログラミング言語には、例外処理のための機構があります。たとえば、以下のような構文です。
try { // 例外が発生し得る処理 // ex. ファイルを開く } catch (e) { // 例外が発生したときに、実行する処理 }
例外への対処は実はとても簡単です。是非ここで覚えて下さい。上記のような機構のある言語であれば、catch節の中身を何も書かなければ、例外が発生しても、何事もなくプログラムは動作を続けます。
try { // 例外が発生し得る処理 } catch () {}
全ての例外を潰せば、決して不慮の動作で停止することのないプログラムを作ることができます。ですから、例外が発生し得るコードは、積極的に上記のtry-catch構文を用いて、例外を潰すようにしましょう。
ホームレス死ね発言でメンタリストDAIGOって奴が絶賛炎上中だが、意識高い系不労所得民なんて生き方してる奴のテンプレみたいなもんだ。
10年前にその一歩先のホームレス殺人を唱導して名を馳せたAutomatons Hacking Guideというはてな日記があった。
ブロガーは「華殉」というビジュアル系っぽい名前を付けた自称東大卒国内一流会社勤務で大学院に通う20代後半という設定の男性。平成初期のトレンディドラマの設定みたいな生活をする人がこの世には居るんだね。
「Automatons Hacking」のAutomatonはオートマタとも言い自動人形のこと。原爆とコンピュータの父、ノイマンが提唱したセル・オートマトンという概念があり、これはそのままライフゲームのアルゴリズムなのだが、フランス現代思想が流行するとこれら情報科学の概念を借用してこねくり回す議論が流行した。
その過程で個人を特定アルゴリズムを持って社会的活動をする自動人形と扱う社会学的手法などが出来た。この辺まではAIの自動学習のベースでもある。
するとこれが人文系に逆輸入されて罵倒や見下しに使われるようになる。自分で考え経験してアップデートし続ける人生を送る人間じゃなくて、与えられたアルゴリズムに社会的入力(引数付き関数)を与えると安定した反応を出す人形として扱う。それは群衆のアナロジーでもある。群衆に属さず上から俯瞰する観察者が自分だ。だから「俺は他の大衆とは違う」と思いたい意識高い系の若者はこのソーカルにコケにされたポモの概念無断借用的な考えに靡きやすい。
ビジュアル系みたいな名前でトレンディドラマみたいな生活を送る華殉は人文家ポモの薫陶を受けている事が判るね。
ハッキングはコンピュータハッキングの事だからこのオートマタに普段の処理とは違う入力を直接与えて愉快犯的に恐慌状態にしたり自分の思うままに操縦する事を表す。
おや?メンタリストっていうのに似ているね。やってる事も知的スノッブの基礎もフォロワーを釣ったり釣られたりする部分も。
オートマタハッカーを名乗る華殉だったがかなり誠実な性格だった。自意識に。
実存の強さ、自意識の高さ故に「群衆の俯瞰者」に惹かれるのであるから自意識に誠実なのはありがちだ。
例えば
・批判されてメタから見ている姿勢は崩さないが相当数のレスをする。
・「安全地帯から言うだけで実際には殺せないだろう」と挑発され熱くなり「自分は実際ホームレスを殺す」と言ってしまう。
・ブログ副題に「〇〇劇場」と書いていたのだが、ホームレス殺人エントリなどで風呂無駄氏にはっきりと拒絶を受け、直後に外してしまう。
・Twitterで「痛い」ツイートをした直後に「ちんこまんこちんこまんこ」というツイートを十数回して流す。
そういえばメンタリスト君も動画の炎上コメントを数百個削除しているようだ。コメントが数百になると閲覧も大変なのに熱心だよね。
華殉はそもそも最初はgoogleの開発がどうとかアップルの製品哲学がどうとか、ニーチェの超人がどうとか、今では意識高い系のテンプレみたいな事ばかり書いていた。でもPVが伸びなかった。そこに「ホームレスの人権なんて行使される事も無い状態だろ」佐川ニキ「ホームレスに人権無いとかいい年してバカじゃねーの」という誤解みたいな論争があり、そこにホームレス殺人エントリで割り込みPVを浚ったのであった。
こんな華殉だったが最後はギーグ精神論的なものにシフトしてフェードアウトしていった。ホームレス殺人や偽善批判などの挑発的エントリから手を引いた理由は増田が見たところ以下による
善への挑発をしたらはてなのリベラルが直情的にひどいと吹き上がる反応をする事を期待していたがネットには宮勤め以外の人間も居り特に不良の経験を持つ人間は喧嘩慣れしている。更にポモ以前の思想の素養がある人間は同系の人間の実存をむき出しにして効果的に怒らせ誘導する術を持つ。これらによって「劇場」が状況劇場になってしまい、実存を開陳しすぎ、刺さり過ぎた。思想系の人間が実存の剥き方を知っているのは自分がその動機(実存のカバー)で思想なんてものに惹かれているから。
・自分への賛同者に底辺のテンプレネトウヨみたいなのが多かった。
ニーチェ援用したりしてるのにルサンチマンで歪んで挑発されると安定した出力する連中に擦り寄られたら立場が無い。というかなまじっか思想なんてやってるので羞恥心で「あ゛あ゛あ゛ー」となる。同意されて懸命に距離を取りたがる姿は侘び寂びが漂っていた。でもこれは華殉も悪くて過去エントリやTwitterではテンプレ的なデマや「自分の税金が外国人の生活保護に吸われて」みたいなテンプレを良く書いていた。そもそもそれってニーチェのルサンチマンそのものじゃね?
子供の主体にとって世界は暴力であり規範を強制してくる装置だ。特に「若者」になり大学や院に進むと知で征服した自分の世界と隷従を求められる外の世界の格差は大きくなる。オートマトンハッキングとメンタリストの行動が似ているのは共にこの需要を相手にするものだからだ。
変数や構文などのプログラミングの基礎は覚えた人向けに、ソースコードを書くときのコツを紹介していきます。どれも今日から実践できるものばかりです。他のプログラマと差をつけることができる技術ですので、ぜひ意識するようにして下さい。良い子はまねしないで下さい。
理想は、aやxなどの一文字です。ただし、これだけだと26文字しか使えないので、a1, a2, ...のように連番でグルーピングすると良いです。
また、変数の宣言と使用箇所が離れた場合に、変数の型がすぐに分かるように、たとえばint型であればi1, i2, ...、string型であればs1, s2, ...のように命名すると、読む人に親切で自分もミスしにくくなります。
変数名を長くするのは、以下のデメリットがあるため、絶対にやめましょう。
多くのプログラミング言語には、クラスや関数といった機能がありますが、これらは基本的にライブラリ提供者などが使う想定の機能であり、一般のプログラマが使うのは好ましくありません。したがって、クラスや関数はなるべく使わないようにして下さい。
不要な関数を作らないためのテクニックには、以下のようなものがあります。
まず、関数の引数に「フラグ」を渡し、関数内部で処理を切り替えれば、1つの関数で複数の処理をすることができます。
function f(i) { switch(i) { case 1: // i = 1のときの処理 break; case 2: // i = 2のときの処理 break; case 3: // i = 3のときの処理 break; // ... } }
この方法は、以下に述べる「変数の寿命を伸ばす」効果もあります。つまり、この関数内で宣言された変数は、すべての処理で共通して使用することができます。
クラスに不要な関数を作らないようにするには、「継承」を用います。複数のクラスで用いる関数を定義したクラスを1つ作っておき、そのクラスを継承すれば、新しいクラスに関数を定義する必要はありません。
理想的には、プログラム内のすべての関数を同一のクラスに定義し、それを継承するべきです。そのようなクラスは俗に「神」と呼ばれ、その利便性からプログラマからはこの上なく尊ばれています。
class God { f1() { // 関数1 } f2() { // 関数2 } // ... } class C1 extends God { // 何も書かなくても上の関数が使える! } class C2 extends God { // 何も書かなくても上の関数が使える! } // ...
変数は宣言する場所によって、ソースコードのどの範囲から参照できるかが決まっています。この範囲が広いことを、「変数の寿命が長い」と言います。
たとえば、以下のコードのaは、関数定義の外側からは参照することができません。
function f() { var a = 1; return a; }
一方、以下のコードのaは関数の内外どちらからでも参照することができます。
var a = 1; function f() { a = 2; return a; }
せっかく作った変数がすぐに死んでしまうのは、非常にもったいないです。ソースコードの表面には現れませんが、変数を作ったり捨てたりするのには、計算コストがかかります。したがって、寿命の短い変数を作りすぎてしまうと、プログラムが遅くなってしまいます。
また、変数の寿命が長いということは、変数をたくさん作らなくても、1つの変数を色々なところで利用できるということであり、とても便利です。たとえば、上記の前者のコードでは、関数の外部からaの値を参照したくなっても、参照することができません。後者のように書いておけば、プログラムのどの箇所からでも、aの値を参照したり、更新することができます。したがって、変数の寿命を長くするとプログラムを変更しやすくなります。つまり、保守性が上がります。
例外とは、プログラムが予期しない処理をしようとした場合に、プログラムの実行を停止し、呼び出し元にエラーを通知する機能です。たとえば、「test.txt」というファイルを開こうとしても、そのファイルが存在しない場合は、例外となります。
例外が発生すると、プログラムが停止してしまうため、非常に困ります。したがって、プログラマは例外をきちんと処理しなければなりません。
ほとんどのプログラミング言語には、例外処理のための機構があります。たとえば、以下のような構文です。
try { // 例外が発生し得る処理 // ex. ファイルを開く } catch (e) { // 例外が発生したときに、実行する処理 }
例外への対処は実はとても簡単です。是非ここで覚えて下さい。上記のような機構のある言語であれば、catch節の中身を何も書かなければ、例外が発生しても、何事もなくプログラムは動作を続けます。
try { // 例外が発生し得る処理 } catch () {}
全ての例外を潰せば、決して不慮の動作で停止することのないプログラムを作ることができます。ですから、例外が発生し得るコードは、積極的に上記のtry-catch構文を用いて、例外を潰すようにしましょう。
昔の職場は、Cで引数を見るときにargv[]にNULLが入ってるかどうかで引数の数を判定してたりした。
int main(int argc, char*argv[])
{
for (・・・) {
if (argv[i] == NULL) // 引数の終わりの判定
}
}
それがバグることがあったので、普通にargcを見るようにして「デバッグしました、原因はコレコレです」と報告したら「よくそんなの分かったな」と感心されたことがあった。
個人的には、それまで本やコードで、引数の数をargc以外で判定してるコードを見たことなかったから、その職場のコードを見て新鮮な驚きがあったんだけど。
「独学でかじってるやつは変な癖がついてダメだ。使えない。なにも知らない新人のほうが素直で延びる」とか言ってる人をたまに見るけど、ネットや本で勉強しないで、職場で教えてもらうだけのほうがむしろ変な癖がつきやすいと思うわ。
良い言語だと思うが、不満がある。
という愚痴がある。他人の書いたものを読む分には良い言語だと思うよ。
型ヒントはコンパイル時のエラーにならないじゃん。だったら、いらなくね?タプルは複数の値を返すときに使うのね。Go みたいだね。または Ruby の Struct みたいな。
あれ嫌いな人おるのか。俺も好きじゃないが。純粋に Haskell と同じ文法だったら良かったのにね。
アレはキモいね。素直に ?! で良いと思う。というか、Python は英語圏の人も納得はできないだろ、っていう文法が多くないか?
というのは同意する。ただ、書くときにそうは思わない。例えば、with 構文は Ruby の方がブロックを抜けたらクローズするという方針のが良いと思う。
仕事でPythonのコードに触れることになった。Djangoアプリ。
「urls.py で リクエストURL とビューのマッピングをします」 → ふむふむ
「views.py に定義されたビューで リクエストを受け取りレスポンスを返します」 → うんうん
「引数で渡される リクエストオブジェクトはこれ https://docs.djangoproject.com/en/3.2/ref/request-response/ 」 → 予想通り
同僚により実装済みの views.py を IDEで開く。 引数にrequestがある。うんうん。
requestにマウスをかざしてみる。
→ IDE無反応
まだ私は気づかない。不審に思いながら、requestの中に詰まっているモノ(method とか header とか body とか)のラインナップが現れることを期待して
request. とタイプしてみる
→ IDE無反応
ここで私はようやく、置かれている状況(相手にしているのはPythonスクリプトであること)に気づき、発狂しそうになった。
型付けに慣れきっている私にとっては
InfinityはJavaScriptが標準で持っていてどこからでもアクセスできる定数(読み取り専用変数)の名前。その名のとおり無限大を表す
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Infinity
min, maxはこの関数内で定義されている普通の変数。定義がないように見えるかもしれないが、引数のところに書いてあるので使用できる
で、valueにはたぶん文字列が入っているのでparseInt(value, 10)で10進数の数値に変換するわけだが(parseIntの第二引数は基数)、
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/parseInt
このときvalueが未定義だったり、まったく数値化できない謎の文字列が入っていたりすると「NaN」という特殊な数値になってしまい、こいつは厳密には0ではないため問題を引き起こすので、そういう変な値がとれてしまった場合はちゃんと0にする必要がある
「parseInt(value,10) || 0」と書くことにより「左辺(parseIntの返値)を真偽値とみなして判定し、もし偽として判定される値(0, NaNのほかnull, undefined等が該当する)であれば||の右辺(0)を採用する」という意味になる
.clamp()って標準のメソッドにあったっけ…?まあ一般的に想像すれば、数値がmin ~ maxの範囲を超えていたら範囲内におさめるってことじゃないの
抽象に依存するってことなんだよね。発想が抽象的でむずかしい。
以下に示すbeforeコードの欠点は、IOに関係する部分とビジネスロジック(誇張)が密結合していることで、このメソッドを変更する理由が複数存在している点である。(単一責任の原則に違反)
変更理由は、IOにnullが入ってくることを考慮するとか、暗号化アルゴリズムを変更するあたりがぱっと浮かんだ。
afterのコードは、readerとwriterを引数から受け取れるようになっていて、インターフェースに依存するようになって、単一責任の原則を守るようになった。
```
# before
def encrypt
end
end
# after
end
end
```
まとめ