Make組ブログ

Python、Webアプリや製品・サービス開発についてhirokikyが書きます。

JavaScriptのグローバルマッチする正規表現でtest()、exec()すると状態が残る

今日はちょっとしたメモ書きです。

JavaScriptでグローバルマッチの(gオプションを付けた)正規表現で、 正規表現.test() をすると実行した状態が残ります。

> const FOO_REGEX = new RegExp('fo+', 'g')
> FOO_REGEX.test('fooooo is foo')
true
> FOO_REGEX.test('fooooo is foo')
true
> FOO_REGEX.test('fooooo is foo')
false

正規表現.exec() でも同様です。

> FOO_REGEX.exec('foooo is foo')
[ 'foooo', index: 0, input: 'foooo is foo', groups: undefined ]
> FOO_REGEX.exec('foooo is foo')
[ 'foo', index: 9, input: 'foooo is foo', groups: undefined ]
> FOO_REGEX.exec('foooo is foo')
null
>

グローバルマッチする正規表現.lastIndex というプロパティに、「今現在どこまで処理したか」を記録します。 .test().exec() ではその場所から次にマッチするまで処理されるので、このような挙動になります。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test#using_test_on_a_regex_with_the_global_flag

ローカル変数の場合に問題はありませんが、 グローバル変数にグローバルマッチする正規表現を置いている場合には状態が残るので注意しましょう。主に 正規表現.replace() のために使うのでグローバルマッチが良いけど、該当の文字が存在するかのチェックだけで使いたい場合などが考えられます。

対処法の考察

ここは単純にグローバルマッチをやめるのが良いと思います。

> const FOO_REGEX = new RegExp('fo+')

FOO_REGEX.lastIndex = 0 のようにすると状態を初期化できますが、グローバル変数の状態を更新するのは美しくない印象です。

「でも主に .replace() を利用したいのでグローバルマッチを付けておきたい!」ということもありますが、この場合は、うーーーん??!!! 正規表現の文字列をグローバル変数に定義しつつ、2種類の正規表現も定義するとか?ちょっと他のアイディアもあれば教えてくれると嬉しいです(すいません)。

他には 文字列.match(正規表現) を使う方法もあります。文字列全体を検証した結果が返されるので、存在のチェックだけをしたい場合に無駄な処理が多くなります。短い文字列しかない前提であれば、これでも良いかと思います。

> 'foooo is foo'.match(FOO_REGEX)
['fooo', 'foo']

まとめ

グローバルマッチする正規表現.test().exec()正規表現に状態が残るという話をしました。

執筆:Kiyohara Hiroki (@hirokiky)Shodoで執筆されました

村社会はどこにでも

ふと思ったのですが資本主義も一歩引いて考えると村社会と言えるのではないでしょうか。

資本家が多くの力や発言力を持っているというのは、周知の事実だと思います。 この資本主義も多くの人が参加しているようで、実は狭い範囲の人がそのルールを握っています。

「村社会」 集落に基づいて形成される地域社会。特に、有力者を中心に厳しい秩序を保ち、しきたりを守りながら、よそ者を受け入れようとしない排他的な社会をいう。しきたりに背くと村八分などの制裁がある。 同類が集まって序列をつくり、頂点に立つ者の指示や判断に従って行動したり、利益の分配を図ったりするような閉鎖的な組織・社会を1にたとえた語。談合組織・学界・政界・企業などに用いる。

goo国語辞書「村社会」 https://dictionary.goo.ne.jp/word/村社会/

たしかに資本主義はよく機能するシステムですし、僕は社会主義共産主義が良いと話を展開する気はありません。 資本主義の問題について論じるのも、マイケル・サンデルマルクス・ガブリエルに譲ります。

でも僕が怖いなと思うのは、皆が実はジョーンズタウンで生活しているのでは?という疑念です。 規模が大きいだけの村やエコーチェンバーの中にいるのでは?という仮説です。

ジョーンズタウンは、アメリカ合衆国キリスト教新宗教(カルト)・人民寺院によってガイアナ北部に開拓・設立された町(コミューン)。(中略) 1978年11月18日、この人里離れたコミューンで計918人の集団自殺を決行したことで世界的に著名になった。

Wikipedia「ジョーンズタウン」 https://ja.wikipedia.org/wiki/ジョーンズタウン

もちろんこれは少し悲観的すぎる見解です。ですが「僕たちは案外狭い社会的価値観の中で生きているのでは?」と疑うことはできます。そして多くの人が言う 「お金が欲しい」というのは実のところ資本主義という村から脱出したい という願望にさえ思えます。

というよりも資本主義にしろ、日本社会、Twitter、コミュニティ、スタートアップ界隈にしろ、規模が違えど 村社会らしさはどんな集団も持っている ということです。

たとえば資本主義は一部の人(資本家)の声が大きくなりやすいシステムです。実際に力も持っていて人も動かせます。 TwitterなどのSNSも、それを作る人やレコメンドのAI、バズりやすい世俗的な記事の価値観が支配的になり得ます。 オープンさを大切にするコミュニティでも実は「中心となる人に好かれないと居心地が悪い思いをする」ような閉鎖性を持っていたりします(常にオープンな心で人と接するのは誰しも難しいものです)。

日本の閉鎖性を批判するひろゆきが、ファンに囲われた閉鎖的な村を形成していったように、どこにもそれは現れます。 極端な例ではオウム真理教サティアンや、連合赤軍の山岳ベースがありますが、その異常な状況も歴史を見れば徐々に歪んでいったことが分かります。

僕たちは案外、排他的で小さな村の中に生きています。資本主義という村、日本という村も、大きなようで実は小さく狭い価値観に左右されています。

なので、少し過激なくらいオープンで反発的なほうが良いのかもしれません。 人間の心には、閉鎖的になりたい欲求が常にあるからです。

執筆:Kiyohara Hiroki (@hirokiky)Shodoで執筆されました

僕の飼育員を募集しています(FANBOXを始めました)

pixivFANBOXを開設しました。

hirokiky.fanbox.cc

Make組ブログでは比較的ちゃんとした内容を書いていますので、より緩やかで内容を保証しないものは今後FANBOXで書く予定です。 このブログにも書いているような「考え方」タグの記事なども、今後はFANBOXで書くかもしれません。

ぜひ支援、フォローいただけると嬉しいです。

FANBOXで投稿することや内容については以下からご確認ください。

www.fanbox.cc

執筆:Kiyohara Hiroki (@hirokiky)Shodoで執筆されました

イーロンマスクの「開発の5ステップ」をまとめました - あなたの要件はアホだし、そのプロセスも要らない、すぐ最適化するな。

イーロンマスク氏がスペースXを案内するという動画(Starbase Tour with Elon Musk PART1)の中で語られた「開発の5ステップ」が僕的に衝撃でしたのでまとめます。

この内容、心底素晴らしいのですが、元動画では話が少しとっ散らかっていますし専門的すぎます。 僕自身、何度も内容を思い返して役に立ったのですが、見直すたび読解に苦労するので自分のためにまとめ直しました (ありがとう、僕!愛してるよ!)。

以降については、イーロンマスク氏が語る開発の5ステップについてまとめています。 余力があれば、自動字幕ありで動画を見ながらのほうが、イーロンマスク氏の熱意を感じられて楽しいと思います(下の動画では、この話が始まる辺りから始まるようにしています)。

youtu.be

イーロンマスク、開発の5ステップ

開発の中では以下の順序を必ず守らないといけません。

  1. 要件をアホのままにしないこと。誰しもがアホにするので疑う
  2. プロセスを削除する。無駄なのを積みたがるので徹底的に減らす
  3. シンプル化・最適化する
  4. サイクルを速くやる
  5. 自動化する

絶対に逆行してはいけません。

ステップ1:要件は必ずアホになる。アホのままにするな

要件は必ずアホになります 。それはあなたが書いても、誰が書いてもそうなります。 なので疑い、アホのままにしないでください。

とくに優秀な人が書いた場合、誰もが「完璧だ」と錯覚してしまい、質問できなくなるので危険です。 常に疑う必要があります。「その要件はなぜ必要なのか?」、「意味があるのか」と。

そして要件には署名すべきです。その要件を決めた人が責任を持って行動しなければいけません。たとえば2年前のインターン生が、その要件の説明責任を果たせるでしょうか?ランダムに思いついた要件を、責任を取らずにいなくなってしまいます。

(注)

ここでいう要件はロケットに必要な耐荷重性能であったり、発生する振動の許容量などのことだと思われます。

ソフトウェア開発の世界でも要らない機能や、無視して良いデータフォーマットの都合、満たすべきでもないリクエスト量の基準などたくさん要らない要件・制約が出てきます。 誰かがなぜか「必要」とした要件がすぐに発生します。疑いを持たないと、それらアホな要件をすぐ許容してしまいます。

この話が興味深いのは 「要件定義をしろ」ではなく「要件をアホなままにするな」と言っている点です 。誰がやっても最初はアホになるから疑えということです。

ステップ2:とにかくプロセスを削除する

要件に対して 人は必要なプロセスを積みたがりますが、ほとんどが不要です

「この要件ならこれも考慮しないと、あれも作ってカバーしておかないと」となりますが、削除してください。

私たちはタイトなマージンでやらないといけません(そうしないと軌道には乗りません)。そのためにプロセスは削除しないといけません。必要なら後で追加できます。むしろ、 追加し直していないのであれば、十分に削除していません

たとえばロケットのグリッドフィンも折り畳む必要はありません。シミュレーションして、迎え角が小さければ問題ないことを確認しています。追加のエンジン出力も必要ありません。そうすれば折り畳みに必要なモーターも機構もすべて不要になります。

(注)

ここでのプロセスをソフトウェア開発でいうと、具体的な動作や画面、モデルやテーブルのことでしょう。どうしてもアレコレと足してしまいがちですが、不要だとイーロンマスクは言います。追加し直すレベルに至ってないのであれば、まだ削除が足りていません。

この話、 常識的に考えればグリッドフィンは折り畳み可能としておきたい気持ちになります 。飛行機が飛び立った後には、タイヤを収納したい気持ちになりますよね?それと似た発想です。ですがそのプロセスそのものを削除してしまった、ということです。スペースXは宇宙に飛び立つ前に、常識という宇宙に穴を開けてしまっています。すごすぎます(グリッドフィンについてはイーロンマスク氏以外の人が思いついたものらしいです)。

ステップ3:やっと、シンプル化・最適化する

シンプル化・最適化を1つ目にしてはいけません。3ステップ目です。 優秀なエンジニアは「そもそも存在するべきでないもの」を最適化しがち です。

なぜ人はそうするのかというと、学校(中学校・高校)では問いに答えることを教えるからです。人は学校で問いに答えるべきであると刷り込まれ、問いそのものを疑うことを忘れています。問いを疑うと、成績を落とされてしまうからです。

なので人は、存在しないものを最適化したがります。

(注)

これは私を含めてエンジニアがすぐにやりたくなるやつです。

  • データ設計やクラス設計をより良くする
  • デプロイの過程を無駄なくする
  • 画面の使い心地・手触りを良くする
  • アクセシビリティを高める

要件やプロセスを削除してしまえば、これら全ては不要になります。「ここのボタンは『OK』じゃなくて『次へ』のほうが良いだろう」なんて、存在するべきでないポップアップや画面・機能、要件について議論しても無駄という話です。

ステップ4:速くやる

上記3ステップを忘れずに速くやります。サイクルの時間を加速しましょう。 あまりにも遅いときは、速く動いてください。ただし3ステップを忘れると、自分の墓を急いで掘ることになります。 とにかく、いつであっても早く・速くやることはできます。

ステップ5:自動化する

最後に、自動化してください。

(注)

この点について詳しく話されていませんが、前後の話から考えるにロボットを使って自動で作る工程を整備することでしょう。 ソフトウェア開発で言うならCIを導入したり、自動デプロイを整備したり、E2EテストやA/Bテスト・BlueGreenデプロイを整備することでしょうか。

イーロンマスクの失敗:モデル3のグラスファイバーマット

私(イーロンマスク氏自身)も、これについて何度も失敗しました。自動化し、速くやり、最適化し、削除したんです。 モデル3の製造であった、3つのバッテリーパックの上にグラスファイバーマットを敷くという生産ラインが、全体を阻害していました。バッテリーパックの生産、ひいてはモデル3の生産ライン全体を阻害していました。

失敗したのは、まずオートメーションを直したことです。ロボットの動作を速くし、経路を短くし、トルクを強くして改善しました。そして速く仕事をし、グラスファイバーマット用の糊を減らすよう最適化しました(糊は全体に塗る必要がなく、糊が延びることを加味して中心部に塗るだけで良かったのです)。

最後になって「これは何のためのグラスファイバーマットなんだ?」と疑問を持ちました。私がバッテリーセフティーチームに聴くと「ノイズと振動低減のためです」と答えたんです。でも彼らはバッテリーに責任があるはずですよね?そこでノイズと振動のチームに聴くと「火災防止のためです」と答えました。お互いが交差することを言っています!まるでDilbertの漫画です!Dilbert漫画のシミュレーションの中にいるのか?と思いました。

よし、わかったと。グラスファイバーマットがある車・ない車で、マイクを積んで走らせました。試して聴き比べると、「で、どっちがどっち?」となりました。違いがなかったんです。結果としてそのグラスファイバーマットは削除したんです。

過程を逆に行ったことで、それまでの自動化や最適化などすべてが無駄になってしまいました。存在すべきでないものを最適化したんです。

終わりに

これは本当にすごい洞察だと思います。まさにリーン的な発想というか、MVP(Minimum Viable Product)を求める姿勢そのものだなと感じます。

「機能を追加しよう」、ではなぜなのか?何のためなのか、どういう数値や体験を改善したいのか。 はたまた、その数値や体験の改善に意味はあるのか?

グリッドフィンを折り畳まないような発想ができているのか? グラスファイバーマットを敷いてるんじゃないか? そもそも存在すべきでないものを最適化してるんじゃないか?

とくに、エンジニアから出発したPdMや起業家は頭に入れておくべきことです。 イーロンマスク氏も言っているように、誰であれアホな要件を出すんです。プロセスを足したがるし、最適化したがるんです。

未来の僕、ぜひ読み直して、頭に入れておください。 動画を見た後に、失敗してたなって思ったでしょ?その後の仕事で何回も役に立ったでしょ?このステップをまとめておいたから、見返して思い出してね。

執筆:Kiyohara Hiroki (@hirokiky)Shodoで執筆されました

ジェンダーニュートラルな単数形のtheyは "they is" でなく "they are" を使う

ジェンダーニュートラルな目的など、 they を単数形で使いたい場合があります。 ですが、その場合のbe動詞は they are になります。 they is とは言いません。

先日、日本人の友人と話しているときに they is ではないのか?とこの話題がでて they are だよと回答しました。改めて間違いがないかを調べてここにまとめます。 僕自身も詳しいわけではないので、違うところや気になる表現があればぜひ教えてください。

こちらのページに、「単数の you と同じように、単数形の they も文法的には複数形と扱い、複数形の動詞を取ります」とあります。

別のサイトでの説明 では "You should ask someone who knows where they are going." のように、 someone が単数でも they には are を使うと書かれています。他には "They are a child. " のような文もありえるようです。

Wikipediaの "Singular they" の項目によくまとまっています ので、引用先を含めて参照されることをお勧めします(上記の2ページはWikipediaからの引用先です)。

en.wikipedia.org

僕は日本人なので、感覚的に何がおさまりが良いかは分かりません。ですがこのように「you are と同じように they are を常に使う」と言われれば納得できます。

イギリス出身の友人に聴いたときも、「they is とは言わない。 they are が良い」と言っていました。 また彼は「僕に対しては he を使ってね。 they と言われると変な気遣いを感じてしまうから」とも言っていたので、「日本人的には面倒もないし全部 they を使ったろ!」とすれば万事解決というわけでもないようです(個人の考え方のうえで言葉を選びましょう)。

またジェンダーニュートラルな代名詞には zie などもあり、 they だから正解というわけでもないようです。この辺りはまだ議論の余地があるようですので、ぜひこの機会に各種引用先などを参照してみてください。

uwm.edu

執筆:Kiyohara Hiroki (@hirokiky)Shodoで執筆されました

【雑記】freeeとStripeの口座連携をせずに登録するメモ

会計ソフトfreeeと決済代行サービスStripeを使っているときの個人的なメモです。 少しややこしい話と、freee、Stripe特有の話がでます。

freeeとStripeの口座連携をすると、お客様からいただいた売上が入るたびにfreeeの明細(決済)を登録してしまいます。そのたびにfreeeで取引を登録するのは面倒ですし、決済手数料も別の明細として登録されます。

さらにBillingを使っている場合は毎日「Billing手数料」と「税金」の明細も登録されます。これはStripeで定期課金をする際に取られる手数料と、その消費税です。税込み処理方式を採用しているので、税金が別で登録されるのもまた面倒なところです。

  • 日々の個別の売上を帳簿に乗せると取引が多すぎる
  • 決済手数料が別の明細で登録される
  • Billing手数料の消費税が、別の明細で登録される

困ったことに、freeeでは1つの取引に対して、複数の明細は登録できません。複数の明細をまとめて1つの入金に紐付けられません。 たとえば会社用に机を100個買ったとして、机一つひとつの購入を「取引」として帳簿付けするのは非現実的です。

Stripeの口座連携をやめてみる

freeeとStripeの口座連携をやめてみました。 freeeにはStripeから週単位で入金されるので、その明細を使います。この取引には売上、決済手数料やBilling手数料を登録し、入金ごとに関係するお金の動きがまとまるようにしました。

消費税の扱いをまとめると以下になります。

  • 売上(課税売上10%)
  • 決済手数料(非課税)
  • Billingの手数料(課税仕入10%)

Stripeは財務レポート機能が優秀で、入金ごとの明細もキッチリと出してくれるので安心です。 上記のように分割して表示してくれるので、そのままfreeeの取引に登録できます。

終わりに

発生主義的にはすべての売上が起こった次点で勘案しないといけない気がしますが、それこそfreeeさん自体はどうしてるのでしょう。日々、数百、数万件の売上があるのをすべて会計ソフトに入力するのでしょうか。

もちろん、お客様からいただいた売上についてや各種手数料については、Stripeの財務レポートなどでいつでも確認できます。なので明細はある状態なのですが、それをどこまで会計ソフトに反映させるか、というレベルの話なのでしょうか。

執筆:Kiyohara Hiroki (@hirokiky)Shodoで執筆されました

inゼリー完全栄養の通販と味のレビュー:美味しい。完全食にしては

8月4日に販売された「inゼリー完全栄養」を買ってみました。

届いたinゼリー完全栄養。

inゼリー完全栄養

今までいくつか完全食を買っていますが、今回はinゼリーということで期待して発売日の8月4日に買いました。 普段は朝食にカロリーメイトを食べるのですが、夏場はinゼリーを食べることもあります。それくらいinゼリーは好きです。

inゼリー完全栄養の通販

こちらの森永ダイレクトストアから購入しました。

https://www.morinaga.co.jp/direct-store/products/list.php?category_id=242

価格は18個入りで5,540円でした。 1個あたり308円 となりますが、1食あたり2個を食べるので、 1食あたり616円 になります。送料は無料でした。

8月4日に購入をして、8月6日の午前中に届きました(首都圏在住)。

f:id:hirokiky:20210806123411j:plain

味のレビュー

inゼリー完全栄養の味を例えると、パイナップルの味が強めのミックスジュースです。公式の「ミックスフルーツ味」という表記に偽りはありませんし、完全食にありがちな豆乳の臭いなどもありません!

inゼリー完全栄養にも、完全食らしい独特の癖(ケミカルっぽさ)は少しあります。さらに普通のinゼリーよりも濃く、水分も少なめで食べにくいです。感覚的には「色々なフルーツを荒く潰して混ぜたものが少し粘ついた感じ」です。離乳食(7ヶ月)のフルーツミックスに近いかもしれません。普段のinゼリーの美味しさまではいきません。

完全食としてはかなり美味しいです。BASE BREADメープル味くらいのクオリティの高さは感じます。僕はこれまでCOMPやHuel、BASE BREADなどを食べてきましたが、その中でも3本指には入ります。でもよく冷やすことはお勧めします。

買いか、どうか

inゼリーが大好きで、フルーツミックスな味もいけるなら絶対買いだと思います。BASE BREADメープル味と同じかそれ以上に美味しいです。 ただ、そうでもない人は少し味見してみてからでも良いかもしれません。

執筆:Kiyohara Hiroki (@hirokiky)Shodoで執筆されました