作りたいものがありすぎる

40歳を過ぎてプログラミングを始めた人の顛末とこれからなど

NativePHP alphaバージョンをwindows10環境で動かしてみた

NativePHP | Baking Delicious Native Apps

なんとLaravelでデスクトップアプリの開発が出来るという変態アプリがでてきたので稼働確認までをやってみました。デスクトップアプリは作ってみたい気持ちがあったのですが、Web系ばかりの私にはハードルが高くて尻込みしてましたが、Laravelでやれるなら!と思ってひとまずいじってみました。

環境

  • windows10 64bit
  • PHP version 8.1.8
  • composer version 2.3.9
  • nodejs 18.17.1

以下の手順に従いインストール Installation - NativePHP

まずLaravelをインストールする

$ composer create-project laravel/laravel example-app

作成したLaravelのプロジェクトフォルダに移動

$ cd example-app

そして nativephpのパッケージをLaravelにcomposerで追加する

$ composer require nativephp/electron

php artisanコマンドを叩いて native PHP関連のコマンドが追加されていればOK!

$ php artisan
Laravel Framework 10.20.0

...省略...

native
  native:build
  native:install          Install all of the NativePHP resources
  native:migrate          Run the database migrations in the NativePHP development environment
  native:minify
  native:publish
  native:queue
  native:serve

...省略...

サーバーの起動を行う

$ php artisan native:serve

  Starting NativePHP dev server… 

 Fetching latest dependencies…

 Installing NPM dependencies (This may take a while)...

 Installing NPM dependencies using the npm package manager...

 Fetching latest dependencies…


 Starting NativePHP app

 Running the dev script with npm...

 Fetching latest dependencies…

しかしエラーとなる

[Window Title]
Error

[Main Instruction]
A JavaScript error occurred in the main process

[Content]
Uncaught Exception:
Error: spawn C:\Users\sakam\study\nativePHP-demo2\vendor\nativephp\electron\resources\js\resources\php\php ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:283:19)
    at onErrorNT (node:internal/child_process:476:16)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

[OK]

(と、同時にアプリのアクセスを許可する旨のダイアログ窓がでるのでこれは許可しておく)

エラーダイアログで検索する(ダイアログ選択でCtrl + Cでメッセ―ジをコピーできる)と、以下のページがヒット。どうもバグがあるらしい

[Bug]: A Javascript Error Occured In The Main Process. · Issue #105 · NativePHP/laravel · GitHub

これらのコメントに従いリンク先のファイルの内容を書き換える。 [Bug]: A Javascript Error Occured In The Main Process. · Issue #105 · NativePHP/laravel · GitHub

To fix this visit => vendor\nativephp\electron\resources\js\electron-builder.js

https://paste.laravel.io/6c7100ed-fc2f-4d27-ad06-060d70e793fd

Replace this file

now run below command in sequence :-

=> php artisan native:install => php artisan native:build win (you will get >error a popup click ok and let complete process). => php artisan native:serve

vendorの中の以下のファイルを

vendor\nativephp\electron\resources\js\electron-builder.js

以下のリンク先のソースに書き換える Pastebin | Laravel.io

以下のコマンドを再度実行

php artisan native:install
# メッセージが出ているがGitbashだと表示されなかった、enterキーを2回程押して先に進める

php artisan native:build win
# 完了時に構文エラーのダイアログが出るがひとまず無視する

# サーバー起動
php artisan native:serve

これで開発用のウィンドウが立ち上がる

まだ具体的いじってはいませんが、alpha版がなんか立ち上がらないなーという方のご参考になれば幸い。

近況

大変久しぶりですが更新します。

近況

おかげ様で業務委託のプログラマーを続けられています。 コロナ禍の状況では運よくほぼ完全リモートで働く事が出来ました。

ですが、ここしばらくは休養しており、新しい技術を学んだりしていたので、その辺の知見をほんのちょこっとでも更新しようかなと思って久々にブログの管理画面を開いた次第です。

来月から復帰し別の所で働く予定です。

やってきたこと

ちょっと特殊なSNSの運用や機能追加、コンシューマユーザー用のサポートサイトの追加改修等を行ってました。 途中から外部認証周りの仕事を主に行うようになり、OAuth2ベースでの認証周りの実装等を主に行ってました。サーバー側にid/passwordを保存してあるサービスから、新たなアカウントを発行して新しい認証方式に変わってもらう為の諸々を、英語のリファレンスを日本語翻訳してAPIとかを使ってごにょごにょしたりとか仕様を切ったり実装したり色々やってました。

スクラム開発を経験したり、リモートだけでしか会話してないメンバーでも結束が強くなってチームで開発したりと様々な経験をさせてもらいました。

開発後期では自分の作ったサービスが実はテレビのCMでばんばん流れてる時期があったりして、でもまだ実装終わってない所あるのに…。とか複雑な心境になったりしました。

けっこうあっさり目ですがひとまずこんなところです。 これからも新しい技術を身に付けていければ良いなと思ってます。

雑食的プログラミング学習方法10箇条

  1. 猿からはじめろ
  2. 金を惜しむな
  3. 最後まで読むな
  4. メモを残せ
  5. errorの出力内容を翻訳して理解しろ、そしてググれ
  6. 駄目なら次、メディアを変えろ
  7. 俺の頭が悪いんじゃない、まだ追い付いてないだけ
  8. 重複部分もひとまず目を通せ
  9. 上手くいかない苦労が後から効いてくる
  10. 出来たら思いあがれ、そして思いあがるな

実は7月からまとまった時間が出来て、この1週間程、新たな技術の勉強を始めて、今やっと最初の目標の環境構築ができる様になりました。(docker-composeで nginx, MySQL,Laravelの開発環境が作れました) その際、理解するまでかなり紆余曲折があって、よくわからない新しい技術の勉強の仕方みたいなものに気付いたので、まとめておきます。

Dockerでの環境構築方法ってプログラミングというよりインフラですが、まあ、学び方は同じだと思うので、多めに見てください。

猿からはじめろ

新しい事を覚えようと思ったら、一番に言いたいのは、とにかく一番簡単で内容の薄いメディアから始めるのをおすすめします。 今回私が失敗したのは、ちょっと上級者向けの本を買って学習を初めてしまった事です。そういうメディアは、多くの暗黙の知識を前提に物事を書いているので、往々に省略された事柄や校正ミス等で、その通りにやっても上手く行かない事が多々あります。そいういうのに一度ハマるとリカバリーがとても難しくなります。解決できないで一時間も悩むと精神的にも参ってきてやる気を無くす可能性があるので、なるべく懇切丁寧で、判りやすいものから始めるのが良いでしょう。

金を惜しむな

ネットには無料のコンテンツが山の様にあります。とても参考になるものもありますが、本当の初心者向けコンテンツというのは、実はとても手間暇がかかりコストがかかるのです。 これは、まったくのパソコン初心者に、講師としてExcel,html,css等を教えていた経験上、確信を持って言えます。 最近プログラミングスクールでの学習がなにかと話題になりますが、授業料がそれなりにかかるのは、教材の作成や、直接教えるコストが馬鹿にならないから、という面も多分にあると思います。

自分自身の力で調べて学ぶスキルに自身がないのであれば、金を惜しまず、スクールなり、高価な本なり、有料コンテンツ等で学ぶべきでしょう。そして、知識だけではなく、『学び方』を学ぶ事を意識するとよいでしょう はい、先生今大事なことを言いましたよー。

最後まで読むな

本や動画の話ですが、ごく基本的な事柄以外は、無理に全部を読んだり見たりする必要は無いと考えています。特に、自分が目的意識を持って学習している時はなおさらです。 今の目標と異なる内容であれば、見出しに目を通して記憶にとどめておくだけで大丈夫だと思います。しかし、基本的な事柄ばかりのものであれば、理解は出来なかったとしても、軽ーく目を通す位はしておいた方が良いでしょう。こんなものがあるんだ、という情報の見出しを保持しておくことが後々役に立つことがあるでしょう。

メモを残せ

プログラミングを覚えるのであれば、メモは絶対必要です。というか、この自分だけの蓄積が自分自身の重要な財産になる筈です。 私は Evernoteや Boostnoteを使って、新しい知識に関しては、とにかくテキストベースメモを残す様にしてます。

f:id:sakamata:20200708164854p:plain f:id:sakamata:20200708232518p:plain

そして、ググってみるのと並行して、このメモでも検索をします。よく使うコマンドとか、出力されたエラーとかurlのクリップとか、Qiita記事のコピーとか、とにかく蓄積させておきます。ツールによってはカテゴリーやタグを付けられるので、私は結構丁寧に分類をしています。 特にサーバーの環境構築に関しては、Qiitaの記事をベースに、自分のメモを追加して、このメモを見れば全部同じに作れる。って位丁寧にコマンドやら注意点を書いて、独自のノートにしてます(なので公開は出来ない)

errorの出力内容を翻訳して理解しろ、そしてググれ

これはそのままです。エラーメッセージの英語がわかんない場合はGoogle翻訳にかけて何て怒られてるのか理解しましょう。さらにその英語文をそのまま検索して、海外のstackoverflowの記事しかヒットしなくても、ちゃんと見に行きましょう。英語のサイトでもブラウザの翻訳機能で日本語化して読めば、結構理解できるし解決できる。さらにそのエラー解決方法が、日本語記事になってなければ、自分が記事を書いてWebに残しておけば後に来た人が助かる事になる。

駄目なら次、メディアを変えろ

それでもなんだか覚えられない、ピンとこない、やる気が出ない、成果が出ない。といった事であれば、そこで中断して次に行きましょう。今の自分に合った知識と情報が絶対どこかにある筈です私はこの一週間で、300ページ越えの書籍を2冊買って実践してましたが、実際に読んで実践したページは100ページ程でした。 でもこれじゃ駄目だと思って、次に動画を探して2時間ほどの実践動画を見ながら実践してみました、しかしこれも、最後までは完走できず、今度は別の基礎的な説明をしている、ウェブサイトをいくつか読み、実践して、やっと自分の目標だったものを構築できるようになりました。

しかし、ここで見て来た本、サイト、動画での知識は、メモを残しているので、時間が経過して技術的賞味期限が切れない限り、いつでも調べられる情報の見出しになっています。

俺の頭が悪いんじゃない、まだ追い付いてないだけ

今回購入した2冊の本は、今の自分にはハードルが高かったです。特に、設定が上手くいかず散々詰まって、問題を解消しようにも、学びたいDockerとは異なる部分でのトラブルだったので、まったくモチベーションがあがりませんでした。(jenkinsのスレイブのssh接続の設定が上手くいかないとか、今の自分にはあまり必要のない事柄で悩んで諦めた) また、自分の目指す方法とは異なる方法論で記述された本の設定方法が自分に合わず、しかも上手くいかなかったので、これも早々に諦めました。どちらも今の自分のレベルでは理解が追い付かない、重要な事柄だったのかもしれませんが、それが出来ない、理解できない事で気に病む事はないと思ってます。

重複部分もひとまず目を通せ

複数のメディアでつまみ食い学習をしていると「最初の方は、どれも同じこと言ってるなー」と思って、ぱらぱらと飛ばしてしまったりしますが、実はこう思える事ってすごい事です。だってそこまで理解が進んで、説明してもらわないでもわかる様になっている訳ですからしかし、その重複部分も流す程度で良いので、ひとまず目を通すことをおすすめします。自分の理解があいまいだった事柄や基本概念が、違う人の言葉で綴られているのを見る事で、より物事の理解が進むと思います。

上手くいかない苦労が後から効いてくる

で、この辺まで来て色々つまみ食いしてい、今の自分に丁度良い教材に出会えると、以前上手く行かなかった際に、苦労して調べた事とか、試していたことが、効いてくる時が来ます(断言)学習曲線が一気に上方向に伸びる瞬間とでも言いましょうか。「あ、このエラーは前にハマった〇〇をしていないからだな」とか、「〇〇の状態なら、次に□□をさせて、そのコマンドは前にメモしたあそこに…」みたいになって来る瞬間が来たらこっちのものです。

出来たら思いあがれ。そして思いあがるな

そして出来たら思いっきり喜びましょう、部屋で踊ったり、人に自慢しても良いと思います。

自分自身の学習力の成果と、多くの先人が残したメディアの力を借りて出来た成果です。人目も憚らず思いっきり喜んでください。そして、俺ってすげえ!と自分を褒めてやってください。

そして学習の為にメディアとして残してくれた先人に最大限の感謝をしましょう。あなたがそれを理解できたのは、先人がメディアを通して、あなたにそれを教えてくれたからです。思いあがった後は、謙虚になって、いつかそのノウハウを次に来る誰かに、伝えてあげられるようになると良いと思います。

今回の学習でお世話になった書籍、サイト、動画等

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

  • 作者:山田 明憲
  • 発売日: 2018/08/25
  • メディア: 単行本(ソフトカバー)

試して学ぶ Dockerコンテナ開発

試して学ぶ Dockerコンテナ開発

qiita.com

tech-lab.sios.jp

tech-lab.sios.jp

tech-lab.sios.jp

note.com

最終的にこちらのサイトの通りに構築したらできる様になりました。 ありがとうございます。

www.membersedge.co.jp

おまけ

たまたま項目が10にまとまったので、私の大好きなアポロ計画のフライトディレクターの『ジーンクランツの10箇条』を紹介します。

引用元: その13「管制官の訓練に出演」:新米宇宙飛行士最前線! - 宇宙ステーション・きぼう広報・情報センター - JAXA

  1. Be proactive(積極的に行動せよ)
  2. Take responsibility(自ら責任を持て)
  3. Play flat-out(目標に向かって脇目を振らず、速やかに遂行せよ)
  4. Ask questions(分からないことは質問せよ)
  5. Test and validate all assumption(考えられることはすべて試し、確認せよ)
  6. Write it down(メモをとれ)
  7. Don't hide mistakes(ミスを隠すな)
  8. Know your system thoroughly(自分の仕事を熟知せよ)
  9. Think ahead(常に先のことを考えよ)
  10. Respect your teammates(仲間を尊重し、信頼せよ)

f:id:sakamata:20090417180922j:plain

これでアポロ13号クルーを無事帰還させたと思うと胸熱。

関連記事: sakamata.hateblo.jp

Laravel unit test dataProvider で変数やconfig 使う場合

コードとコメントで全部表してますがこんな感じ。

unitテストにしろFeatureテストにしろ、データプロバイダを使って、test用の配列データを作るというのは良くやるかと思いますが、 unitテストで データプロバイダ使う際には、

$this->createApplication();

というのを最初に書いてやらないと駄目らしいです。(laravel6系で確認)

    /**
     * データプロバイダ
     * @return array
     */
    public function hogeParams()
    {
        // unitTestでは DataProviderにこれが必要
        $this->createApplication();
        // 上のを入れないとdataProvider内でこんなのが使えなくなる
        $otherId = config('const.hoge-id');

        // この辺にTestで使う配列を記述
        return [
            // 配列宣言
        ];
    }

$this->createApplication();を書かないとこんな風に怒られる

There was 1 warning:

1) Warning
The data provider specified for Tests\Feature\HogeTest::postValidateRequiredIfTest is invalid.
Target class [config] does not exist.

WARNINGS!
Tests: 1, Assertions: 0, Warnings: 1.

追記:

ノウハウとして、$this->createApplication();とだけ書けば良い。という理解でもいいのだけど、これ、実は Laravelのtestsディレクトリにある以下のメソッドを呼んでいるってことですね。

\tests\CreatesApplication.php

<?php

namespace Tests;

use Illuminate\Contracts\Console\Kernel;

trait CreatesApplication
{
    /**
     * Creates the application.
     *
     * @return \Illuminate\Foundation\Application
     */
    public function createApplication()
    {
        $app = require __DIR__.'/../bootstrap/app.php';

        $app->make(Kernel::class)->bootstrap();

        return $app;
    }
}

これ、確かLaravel自体をアプリケーションとまず動かす奴で index.php とかから追える処理で書いている事と基本は同じですね。つまり unit test単体として完結した ピュアなphpunit 環境でtestさせるんじゃなくて、laravelとして動かして動作検証するというか、そんな感じ。 詳しく追ってないけど DataProvider という機能自体がLaravel固有のものなのかな?そんな気がする。

10万円給付金を無限に使う仕組み

コロナウイルスで大変な事になっている地球の皆さんこんにちは。私も大変です。

日本政府が国民一人あたり10万円を給付するとか、しないとか、足りないやばい。みたいな話になってますが、これは今その問題を解決する方法ではなく、先々の事を考えての提案というか妄想です。

半分ネタみたいな話ですが、実は結構前から色々考えていたことの一つの答えみたいなものが、ここ数ケ月で発酵してきたので、アウプトプットしておこうと思います。まあコロナウイルスに感染して死んじゃう可能性も0じゃないので。

では先に結論。

何処の国でも良いです。その国の政府は国民一人あたり日本円でおよそ10万円を数か月配り続ける予算を使って(後払いでもOK)再分配が可能なスマホアプリの電子通貨システムを発注するなり作るなりして欲しいです。そうすれば結構多くの人がピンチを脱したり、幸せになったりするかもしれないよ。という話。

は?お前何言ってんの?というツッコミを無視して話を続けます。

政府が確約することは

  • そのシステムの利用者はこの国のこの人で間違いない事を証明する
  • そのシステムを維持運営する予算を毎年出す
  • これは確かにウチの国のお金ですよ、と確約すること

です。

誰だお前

そもそもお金とは何か?とか、そういう話を10年以上延々調べたり考えて、新しい経済システムを作りたくてプログラム覚えてプロトタイプを作ったりして現在は職業プログラマーのおっさんです。

でもまあ仕組を考えて、ショボくても自分で作れても、皆がそれに価値を感じて使ってもらわないとそれは「お金という仕組み」にはならない訳です。

でもビットコインだって最初は冗談半分でピザと交換されたのに、今や普通に取引されています。羨ましいぞサトシナカモト。

お金大事、なのに稼げない

さて、そのお金ですが、日本のお札には日本銀行券、って書いてありますが、最近流行りのスマホの「なんちゃらペイ」にあるポイントと、日本銀行券って同じお金ですよね?ゲームに出て来る「ゴールド・ルピー」なんていう「ゲームのマネー」と見た感じ大して違いはないのに、レジてピッってやればちゃんと使える。便利。 そして、足りなくなったら、クレジットカードとか銀行のお金でチャージすればいい。すげー便利。 でも銀行に振り込まれるそもそものお金は、働かないと枯渇する。チャージもできなくなる。何も買えなくなるかも。でも働くに働けない状態が、まだ続きそうですげー不安。

だから政府が国民の生活を守る為に、支援金を配るべきだというのはもっともだと思います。

要は国民全員の銀行口座にピッってチャージして欲しいわけです。で、当面は毎日生きるのに必要な食べ物や電気の支払いや生活必需品を買えて、なんとか生きていける様にして欲しい。

でも、本当に全員なの?とか、早くしろよ、とか、もっと給付されないと全然ヤバイ、とか喧々諤々やってるあいだにも、仕事は出来ず、残高はひっ迫し、気持ちに余裕が無くなる。

そういうの本当に辛いと思います。まかり間違えば病気やお金で絶望して死ぬかもしれないなんて本当にしんどい。

でも、こんな時に私個人ができることって仕事以外であんまりない。なので、ちょっと非現実的だけど、もしできたら良いな。みたいな話として読んでください。

私はお金の歴史に学んで、新しいタイプの電子マネーのようなものを作りたい。と考えています。

f:id:sakamata:20200508004807p:plain

どういう仕組みか?

政府主導のスマホアプリ

生活に必要な最低限の額(以降『ポイント』と呼称)が、毎月でも、週に1度でも、毎日、でも良いです。きちんとチャージされる様になる仕組みです。

ひとまず、一月あたりで一人10万ポイント

で、このアプリ、スマホ同士でポイントをやり取りできます。レジの機械でピッってやるのが難しいなら、私でも作れるQRコードとかで送り合えるものでも良いです。つまり個人のスマホ同士でポイントをやり取りできる。QRコードだから、遠くの人ともやり取りできます。

スマホ持ってない」とか、「うまく使えない」って人は最初の月に給付される10万円の替わりにアプリの入ったスマホを配布してもらうなり、購入するなりして通信会社と契約してもらいます。デジタルデバイドの問題は、それこそこの給付金である程度なんとかできると思ってます。

そして政府が「これ、お金として使えます」って言えば良いだけ

むしろ、この「なんちゃらペイで払います」って言ったのに、お店とか売る側が、「そんな変なマネーじゃ駄目だ、福沢諭吉よこせ!」みたいに受け取り拒否をすると、むしろ罰金にするとか、罰則設けても良い位です。だってお金なんだもん。

でも、そうなれば、私たちはこれで毎月の最低限の生活をまかなうことができる訳です。これでスーパーやコンビニで食料買っても良いし、電気代を払っても良い。家賃を払っても良いわけです。そして当然これは国が「お金として使えます」って言っているので、給料として社長が従業員に配っても良い訳ですよ。

スーパーやコンビニはレジに自分の店のスマホの口座のQRコードを紙に印刷しておけばOK(法人端末がー!とか問題があるなら、この際店長さん個人の端末とかでも良いです)会計の時に、提示された金額が確かに自分のスマホに振り込まれた事だけを確認できれば良いわけです。

電気も家賃も同様です。ウェブサイトに法人口座に相当するスマホQRコード張っておけば支払いができる訳です。

だれが払ったのか?スマホアプリなら管理や証明が可能です

要は銀行の口座がアプリになっている様なものなので、誰からポイントが送られて、誰に送ったか?が、最初から通帳とか確定申告の時の資料の様に管理出来てるわけです。

でも、「誰とやり取りしたらわかるとか嫌」とか、「エッチな本の購入履歴とかマジ勘弁」となるので、電話番号とか名前じゃなくても、それに紐づけた暗号化されたIDでも、そのアプリの利用者の一意の情報が利用者全員がお互いにわかっていれば、まあ問題ないかと。

そんなこと言って月10万とか財源どうすんだ!

と思うかもしれません、確かに最初の製作費と月々の維持管理費はそれなりにかかると思いますが、それでもせいぜい、超有名なウェブサービスの運営費位か、それ以下でなんとかなると思います。上手くいけば、銀行のATMをはじめとした口座システム開発費や維持費よりも安価になると踏んでます。そして…

月10万の財源は、皆さんが毎月やり取りをする月10万ポイントから徴収します

なにを言っているのかというと、このシステム、3か月位一切使わないで放置していたらどうなるか?

合計30万が振り込まれていると、思うじゃないですか?

ところがどっこい、残高は10万です。

つまり使って無いと、その分は他の人の財源に回されます。 毎月10万、きっちり使って残高を0にすれば次の月はまた10万入ります。

逆に言うと、月末に30万位溜まっていても、最高で残高10万位まで減らされます。でも、全部は取られませんし、必ず全員が一定量のポイントを国から保障される訳です。

この理不尽な現象に名前を付けるとすれば『所得税』とでもいいましょうか。でも、このシステムを使っていれば毎月10万は必ずもらえる。つまりベーシックインカム型、再分配機能内包の通貨システム』という訳です。

さて、これでは支払いをされる側があまりにも損をしますが、損をしないタイプの説明をする前に、ひとまず現状の数字の流れの全体像を具体的に説明します。

仮に、このなんちゃらポイントの参加者が10名だとしましょう。最初の月に全員に10万ずつが渡り、政府の支払いは100万になります。

10人は生活の為にお互いのモノやサービスとポイントを交換します。現在仕事が出来ずほとんどが生活費で消える人のポイント残高は、ほぼ0に近くなり、逆に今も運よく仕事があったり、モノやサービスを多く提供した側には、20万の儲けが出たとしましょう。

仮に利用開始から一か月が経つ頃に、10人中3人が30万溜まったとすると、10万(最初から)+20万(儲け)3人の合計は90万 そして残り7人のわずかな額を合計をするとちょうど10万となります。そして全体で見ると 90万 + 10万 で合計100万、合計額は当然変わりません。

そして月末になると、30万の口座の人は20万が引かれ、残高10万。 3×20=60万を残りの7人に分けて全員が10万に戻る。という訳です。

もっとも、これはずいぶん極端な例で、「頑張って働いたのに20万も取られるなんてふざけてる!」と思ったかもしれませんが、当然です。なのでルールを少し変えまましょう。

30万バラマキからスタートするともっと嬉しい

今度は3か月目までは、新規で10万ずつが必ず振り込まれるとしたらどうでしょう?つまり3か月放置すると30万迄きちんと溜まります。その時点での10人全員での合計は300万です。ベースラインをあげた上で、毎月10万を必ず全員に配る分だけを全体の余剰から集めます。

今度もさっきと同様に3人の一月の儲けが+20万だったとしましょう。 元々全員が30万溜まった所からスタートしたので、儲けた3人が持っているのは 30+20= 50万です。 これが3人で合計150万。 残りの7人が持っている合計額は、全体の300万から150万を引いて、150万です。(さっきは10万だったのに!)

これなら残高10万未満の人に負担する額は、前よりも少なくて済む事がわかるかと思います。運が良ければ再分配もしなくて済むかも!

…というのも実は極端な話で、実は総額が増えた分、インフレが起こるのと、流動性が上がって云々、となるので、実はそんなに上手くは行きませんが、全体として余裕が生まれるのはわかるかと思います。

さらに考えを極端にしてみます。 もっと財源を豊富にしましょう。そしてある程度残高が溜まってから取られるルールをもっと甘くしましょう。100万から1万だけ引かれる様にする?それとも400万位から50万位にする?1000万なら300万位?より溜まった人からはより多く取った方が良い? …なんとなく従来のお金の仕組と『所得税』に似てきましたね。つまりそういう事です。

じゃあ、このバランスをどのへんで保つのか?というのが大きな問題であるにはちがいないですが、たぶん福祉国家を目指すなら、このゲームの参加者全員が「健康で文化的な最低限度の生活」が出来る位、毎月配分される位がちょうど良いのではないでしょうか?

そしてこのゲームを10人ではなく何億人という単位でやる訳です。

つまり、このシステムで徴収された金額は確実に他の参加者の為に使われ、新規のポイント発行も上の例だと、3か月目以降はなくなり、毎月必ず全員に10万位が手に渡ります。しかもその合計は常に一定で、中で数字が循環するだけ。という仕組みです。 なので、ぶっちゃけると国家が運営する「お金」「税金」「社会福祉」や「再分配」という仕組みを、デジタルマネーの仕組ですべてやってしまおう。ということです。でもその税金は既にこの仕組みの中自体で取って再分配されているので、これ以上税金を取られる必要性も意味も無い訳です。

なんか騙されてる気がしないでもないですが、私に言わせれば、実は従来のお金の仕組自体が絶妙に人を欺いた仕組だと思ってます。

さて、ではこのなんちゃらペイシステムで「所得税」がどんな配分になったとしても、絶対に損をしない方法をあらかじめ言っておきます。現在の経済状況がどんなに豊かな人も、大ピンチの人も、この戦略はほぼ一緒です。

『次の再分配の日までに残ってるポイントを全部使いきること』

たったこれだけです。

宵越しの金を持たなければ、自分の持ち金は絶対減らないのです。さらに必要最低限の額は再度支給されるのです。

f:id:sakamata:20200508004846p:plain

ベーシックインカム反対の意見でよく出るのが「税源をどうするんだ」とか「全員にお金が支給されたら、誰も働かなくなる」という話がありますが、この仕組みの中で財源は、投資した額だけが中で循環するのみですし、再分配されるのは、健康で文化的な生活をする為の最低限の額だけです。それでも足りない分は従来通り、ある程度働くなり従来の社会福祉を利用するなり、周囲の人たちと支え合う必要があります。しかも今は、コロナウイルスの為に働くに働けない状況の人が格段に増えています。そんな中でこのような仕組みがもし実現できれば、誰にとっても生きるのに必要な最低限をシンプルに保障する。という点でそれなりの効果が期待できるのではないでしょうか。

じゃあ、もう一度。

この仕組みで政府が確約することは

  • そのシステムの利用者はこの国のこの人で間違いない事を証明する
  • そのシステムを維持運営する予算を毎年出す
  • これは確かにウチの国のお金ですよ、と確約すること

というのを是非やってくれると、結構うまくいくと思うんですが、どうなんでしょう。夢物語みたいなものだからなかなか難しいかもしれません。 財源は上の例なら国民1人あたり30万ぽっきりで、そっから先は内部のポイントを循環させますので、それ以上にお金がかかる心配もない。維持費の支払いさえ内部のポイントでやっても良いんじゃないかって位です。

しかし、こんな酔狂を本気にしてくれる政府が現れない場合のプランも当然考えていて、どっちかというとこっちが理想で本命です。

要は上のルールをこんな感じで少し変えれば良いと思ってます。

  • そのシステムの利用者はこの人で間違いない事を他の利用者や第三者に証明してもらう
  • そのシステムを維持運営する予算は利用者同志が出す
  • このスマホアプリのポイントは確かにお金ですよ、と利用者同志が合意し確約する

です。

そのシステムの利用者はこの人で間違いない事を他の利用者や第三者に証明してもらう

一番目が必要な理由は、複数のスマホを持っていたら追加でさらに10万貰える、という二重取得を避けるためです。一人1アカウントが前提の仕組なのでこの辺が必須になります。

そのシステムを維持運営する予算は利用者同志が出す

二番目は運営、お札や貨幣といったモノとしてのお金ではない為、二重会計や不正等の怪しい計算がされることなく、健全な運営維持が続くことが信頼の根拠になります。そして誰がそれを保証し続けるのか?が問題になります。ビットコインなどは独立したアプリケーションと、ブロックチェーンという、個々の端末に共通の暗号化された全員の通帳を持つ的な人の介在しない仕組自体が、それを維持してます。

このスマホアプリのポイントは確かにお金ですよ、と利用者同志が合意し確約する

三番目が特に難しい気がしますが、この仕組みがとても安心して信頼できるようになり、お互いがこの仕組みに騙されても良い。と考える人が増えれば上手くいくはずです。すでにビットコインがある意味でそうなっていますし、既存の「お金」という仕組そのものが既にそうなってますので。

ということで、このシステムを作って、これでピザを売ったり買ったりしてくれる人を募りたい、というのが私の当面の目的です。誰かよかったら一緒にやりましょう。

ちなみに、この仕組みの元ネタを知りたい人は「ゲゼル」とか「自由貨幣」とかとかでググってみてください。

上記の説明は簡略化したもので、実は考えなきゃいけないルールや仕組、起こりえる問題点は多々あります。例えば再分配の時間が決まっていた場合、必ず損をする人が出て来る問題や、既存の通貨との両替や交換、この仕組みを使っての投資や借金はどうなるの?といった問題がありますが、それはいずれかの機会に説明したいと思ってます。

また過去に私が作ったプロトタイプとか(今ちゃんと動きません)いままで考えた事の軌跡はここにあるので、興味があれば見てやってください。

Happy Project 新しい通貨概念をデザインしよう

さすがにプログラマー業界も景気が悪くなってきたので、私も暇ができてしまうかもしれません。なので時間が余ったら新しい技術を学びながら、ショボくて良いのでもまずはこれを作ります。まあ、現状での利用してもらえる信頼度は0ですし、課題も山積みですが、いつか0より大きくしたいと思ってます。

Laravel本番環境が local 設定で動いていて焦った話

本番環境での composer コマンドに注意

10分程本番環境を止めてしまった。とはいえ普段はSlackの通知ばかりでサイト本体は人がほとんど見てないのでたぶんセーフだ。(本当か?)

まず結論

本番環境の composer install では 以下のオプションを付けないと、 dev環境の dusk 等も本番にインストールされてしまうケースがあるかもしれない。最悪動作しなくなるので注意。(envの設定によっては不要かもしれないが未検証)

Exception: It is unsafe to run Dusk in production. · Issue #289 · laravel/dusk · GitHub

composer install --no-dev

そもそも論

これまで本番環境の .env の APP_ENV の設定値が localのままだった、これのせいで composer installでlocal環境での phpunitや諸々が本番環境にも入ってしまっていたようだ。

従ってまず .envの 値を以下の様に書き換えた

本番before

APP_ENV=local

本番after

APP_ENV=production

ここが最初から productionに設定してあれば、そもそも今回の問題は起こっていないかもしれない。

.env を書き換えた後にconfig:clearの際に出たerror

$ php artisan config:clear

In DuskServiceProvider.php line 43:
                                           
  It is unsafe to run Dusk in production.  
                                           

これ、たしかローカル環境でも散々悩んだ DuskがLaravel5.6 ではにっちもさっちも行かなくなった際のerrorで、vendor の dusk内のメソッドで返り値の型宣言しないとerrorになる関係の奴だったと思う。

で、この後composer updateをやったら以下の様な error が出た

#色々あって最後の方
  - Installing composer/semver (1.5.1): Downloading (100%)         
  - Installing composer/ca-bundle (1.2.6): Downloading (100%)         
  - Installing composer/composer (1.10.1): Downloading (100%)         
  - Installing barryvdh/reflection-docblock (v2.0.6): Downloading (100%)         
  - Installing barryvdh/laravel-ide-helper (v2.6.7): Downloading (100%)         
symfony/event-dispatcher-contracts suggests installing psr/event-dispatcher
symfony/service-contracts suggests installing symfony/service-implementation
barryvdh/reflection-docblock suggests installing dflydev/markdown (~1.0)
Package facebook/webdriver is abandoned, you should avoid using it. Use php-webdriver/webdriver instead.
Writing lock file
Generating optimized autoload files
Carbon 1 is deprecated, see how to migrate to Carbon 2.
https://carbon.nesbot.com/docs/#api-carbon-2
    You can run './vendor/bin/upgrade-carbon' to get help in updating carbon and other frameworks and libraries that depend on it.
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover

In DuskServiceProvider.php line 43:
                                           
  It is unsafe to run Dusk in production.  
                                           

Script @php artisan package:discover handling the post-autoload-dump event returned with error code 1

dump-autoload でも同じこと言われる これでも本番は動かない(5分位経って焦っている)

$ composer dump-autoload
Generating optimized autoload files
Carbon 1 is deprecated, see how to migrate to Carbon 2.
https://carbon.nesbot.com/docs/#api-carbon-2
    You can run './vendor/bin/upgrade-carbon' to get help in updating carbon and other frameworks and libraries that depend on it.
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover

In DuskServiceProvider.php line 43:
                                           
  It is unsafe to run Dusk in production.  
                                           

Script @php artisan package:discover handling the post-autoload-dump event returned with error code 1

そこでerror文言でググり冒頭にも張った以下のページに辿り着く

Exception: It is unsafe to run Dusk in production. · Issue #289 · laravel/dusk · GitHub

記載されたコマンド打って本番環境に不要な Dusk含む余計なものをアンインストールできた。

$ composer install --no-dev
Loading composer repositories with package information
Installing dependencies from lock file
Package operations: 0 installs, 0 updates, 34 removals

# 色々削除される(割愛)
  - Removing webmozart/assert (1.7.0)
  - Removing phpunit/phpunit (7.5.20)
  - Removing laravel/dusk (v4.0.5)

Generating optimized autoload files
Carbon 1 is deprecated, see how to migrate to Carbon 2.
https://carbon.nesbot.com/docs/#api-carbon-2
    You can run './vendor/bin/upgrade-carbon' to get help in updating carbon and other frameworks and libraries that depend on it.
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
Discovered Package: barryvdh/laravel-cors
Discovered Package: barryvdh/laravel-debugbar
Discovered Package: barryvdh/laravel-ide-helper
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Package manifest generated successfully.

むしろ今までlocal環境の設定のままで良く動いていたな、と思う。 万一間違ってtestコマンド打っていたらDBが死んでいた。 ちなみに上に出てる Carbon の新しい奴がどうした、とかいう奴は、前に古いバージョンじゃないと駄目な依存パッケージがあったかもで、そのままにしている。

Laravel Eloquentで取得したデータの状態を意識してなかった件

今までDBファサードでデータの取得をしてましたが、最近はすっかりEloquentでデータを取ったり入れたりするようになりました。が、チェーンメソッドをごりごり書く際に上手くデータが取れない時があって、なんで?ってなる事がしばしばでしたが、データの状態をちゃんと意識しないで感覚と経験則と実装時のTry&Error でなんとかしちゃってました。 でも、この辺をちゃんと意識すべきだなと。

経験のある人から見ると「今それ?」みたいな話かもしれませんが、つまりこれです。

まずお馴染みのModelがあったとします。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $table = 'users';

    // リレーションとか scope とかのメソッドが続く

}

それを use App\User; して使って他のクラス内で使える様にする訳ですが、 ごく単純に使うならまずこうですよね。

$user = User::find(1);

DBなら、user tableの主キーとなる id=1 のレコード1件を抽出します。 あとこんな風にも使います。

$user = User::find(1)->get();

とにかく欲しい。これでデータ取得、みたいな時ですね。

また、ちょっと違った条件で呼び出したい際はこんな風に呼んだりもします。

User::where('community_id', 1);

DBで考えると users table の community_id カラムの値が 1の奴だけ、 つまりコミュニティ1に属するユーザーだけを複数あれば取得、みたいな感じですね。

当然こいつもgetして使う訳です。

User::where('community_id', 1)->get();

で、個人的によく使うのがこのパターンで、複雑な階層下のtableなんかを呼ぶ際は、外部キーをベースに値を呼び出して使う。なんていうのがある訳です。

User::where('community_id', 1)
  ->LeftJoin('comments', 'comments.user_id', '=', 'users.id')
  ->where('comments.active', 1)
  ->get();

こんな風にアクティブな該当ユーザーのコメントのみを出す、みたいなニュアンスでクエリビルダゴリゴリ書いて使う感じですね。(リレーションメソッド使えって話もありますが)

で、こんな感じでいろんな形式でデータを取得するわけですが、なんか上手くいかないなー。って場合があって、その原因がわかりました。

$user = User::find(1);
dd(get_class($user));

ってクラス名を出力したら、最初に紹介した奴、それぞれ違うんですね。

$user = User::find(1);
dd(get_class($user));

これは App\User class と出力されます。

つまり、これはまだ只のModelクラスのインスタンスにすぎません。

次にこれ、一件やっている事は上と同じですが、インスタンスされるクラスが異なるんですね。

$user = User::where('id', 1);
dd(get_class($user));

Illuminate\Database\Eloquent\Builder class が出力されます

dd($user)って出力すると量が多くてヤバイ奴です。

Laravelやってる人は経験あると思います。dd() の際うっかりすげえ量のオブジェクトが出力されてマシンがうなってなかなか画面表示されない。って奴ですね。

しかし、これらに ->get() を付与するとさらにクラスが変わります。

$usr = User::find(1)->get();
dd(get_class($user));

Illuminate\Database\Eloquent\Collection class と出力

つまりコレクションクラス(配列っぽく便利に使えるアレ)のインスタンスとして出力されます。

$usr = User::where('id', 1)->get();
dd(get_class($user));

これも同様、 Illuminate\Database\Eloquent\Collection class と出力

コレクションクラスのインスタンスとして出力されます。

つまり ->get() を付けたら実体化してコレクションとして加工や出力に便利に使える状態に変換される訳ですね。

ところがややこしいのはこれ、 ->first() です

ひとまずこの条件で絞り込んで、最初の1件だけを取得する。なんていうときに使います。私は曖昧なデータの取れ方をするのが嫌であまり使わないですが。

$user = User::where('created_at', '>', Carbon::toDay())->first();
dd(get_class($user));

これ App\User class と出力されます。

コレクションでもなくまだピュアなモデルなのかよ!って感じです。

でもよく考えたら、 find(1) と同じ扱いですね。

でもこれらはとても、混乱しがちで間違いがちなんですよね。

first() もごりごりクエリビルダ書いた最後に付けることが良く多くて、取れるデータとして確定するニュアンスなので。 ->get() と同じ認識でいましたが、インスタンスが異なる為、本質も異なるんですね。

なので、余談ですが first() の後には ->get() が付けられて、コレクションインスタンスに変換が出来ます。使い道が今一つわかりませんが。

$user = User::where('created_at', '>', Carbon::toDay())->first()->get();
dd(get_class($user));

Illuminate\Database\Eloquent\Collection と出力

あとこれ、当たり前ですが最後に ->toArray() を付けるといずれも完全な配列となります。

User::find(1)->toArray();
User::find(1)->get()->toArray();

普通の配列データになる

私はこれで必要なIDの配列を取得して、別のModelを呼ぶ際のwhereInの条件にして使うことが多いです。TOP階層から5階層配下(鬼のようなDB構造...)のtableのリレーションでの値を出す必要があったりして、そんな場合に使います。

また、実際のアプリケーションで複雑な検索条件に対応する際の方法として、一度、単純なクエリ find() や where() でデータを呼び出して、get() を繋げないて$queryみたいな変数に入れ、それをさらに様々な処理を経由して条件追加をチェーンメソッドで繋げて、最後に ->get() みたいな使い方をします。

以下のような感じ。

// よく使う例

public function getUser(Request $request)

    $query = User::find($request->id);

    if (!is_null($request->date)) {
      $query->where('date', $request->date);
    }

    if (!is_null($request->name)) {
      $query->where('name', 'like', "%{$request->name}%");
    }

    return $query;
}

で、この関数の呼び出し元で

public function index(Request $request)

    // 上の関数を呼ぶ
    $query = this->getUser($request);

    // この辺に $query->を使ってさらに色々処理を繋げたり加工したり

    // で、最後にこれをしたりしなかったりして
    $user = query->get();

    // 出力
    return view('index', [
        'user' => $user
    ]);
}

みたいな感じ。

ですが、その際にこの辺のデータも持ち方の違いをきちんと意識してないと、なにがなんだかわかんなくなる。という事がありますので、現在のデータの状態を意識しつつ、クエリビルダを繋げる必要があるな。と感じた次第。

でも、この辺、有志のリファレンスサイトEloquent:利用の開始 5.8 Laravel見るとちゃんと書いてあるんですよね。

データの取得の方法論ばかり意識していて、これまではどのクラスのインスタンスの状態であるか?というのを意識してなかった。そういえばdd()で出す際になんか違うな―。位の認識しかしてないという…。

余談ですが、ここに意識が向かったきっかけですが、最近チームで実装をするようになり、後から私のコードを読む人の為に、わかりやすいコードを意識するようになり、メソッドにきちんとアノテーションを書くことも始めました。(最近かよ!)

とはいえ、けっこう俺流で書いてしまっていたのですが、これを書くことで起こった良い変化として、引数にはどんな型のデータが必要で、返り値のデータの型は何なのか?というのを意識的に統一して書くようになりました。

その際の返り値に、じゃあクラスのインスタンスとしては何を書くべきなの?って時に、あれ?ってなってこの記事に至ります。

しかし、返り値については、これまでは単純な配列や数値等、あと、Modelで書いたら、全部内容同じでしょ、位にしか認識してなかったので、今後は返り値が何のClassのインスタンスなのかをきちんと意識して実装できるようにします。