2020-07-29 にっき

昨日のは2020-07-28 にっきだったのだな


冷蔵庫と洗濯機がきた。洗濯機の配管をまだつないでいない。繋がねば着る服がなくなる。 今週を凌いで週末に何か、整理整頓を進めたい。 退去からやれという話だが。


omniauthとなかよくなりつつある


今日職場で自分がgemに追加したオプションを見かけてとっても嬉しかったので私が作りました!!みたいなの出張って書いたりしていた


JSONのテストについて雑にscrapboxにまとめたがscrapboxには双方向のやりとりが無いからTweetしてもらうかブコメしてもらって流行りに流行って自分がブコメエゴサするぐらいまでいかないとコミュニケーションが発生しないんだよな。 やはりscrapboxでメモしつつある程度のところの版をQiitaにスナップショットとしてあげてしまうのがよいのではないか。


Qiitaおじさん業をした。コメントを書いただけだけど。社のOrganizationに参加した。

今朝はn度寝してかなり破滅した感じがする。

子からうつった鼻喉の風邪、妻にうつさないように別の部屋で寝てるんだけど、もってきた唯一の寝床設備であるところのハンモックの設置をやる体力がなくフローリングに直で毛布しいて上に寝るどこでも寝れるギフテッドを発揮している

月末までこれでしのげば妻の寝具、脚付きマットレスが揃い私のマットレスが帰ってきていい感じになる予定。


環境が変わったので通う食べ物屋さんに変化が現れていい感じ。うまい。 ココイチのポークカレー(特に何も具のってないやつ)をはじめて注文してみたけど結構満足出来てしまった、とはいえ何もないので何か足したい。いいのがあれば....

2020-07-29 にっき

ここを手軽に書けるようにするのを怠っていた

最近は引っ越しをしている


4連休でRedmineパッチ会 #1に参加した

redmine-patch.connpass.com

よさそうなissueを見繕ってくださっていて雑に直して3つパッチを投げた。

チケットは

時刻の表記の設定がCSV・PDFのダウンロードで効いてなくてぴえん、と https://www.redmine.org/issues/31637

前へ・次へにtitleつけるやつ https://www.redmine.org/issues/33572

後者の方、雑すぎて2クエリ増やしてしまったので直さねば。


4連休でbitclustとなかよくなったので、るりまに「編集する」のリンクを付けれるようになった。GitHubユーザーのみなさまがたにおかれましては、どのファイルをいじればいいか、どの行あたりなのかを知らなくても編集押せば編集できるのでかなり便利だと思う。

github.com

とはいえ新規でエントリ追加はできないので、やはりこれだけでは足りなくて

  • rdocから未翻訳のエントリをるりまに足す
  • 未翻訳のエントリをみた人が編集を押して日本語訳を追加する

の両輪かなあ。これで編集してくれる人が増えてくれると嬉しいなと思っています。


るりまでいうとbitclustのGraphQL対応を入れたいと考えている。 bitclustではHTMLを出力するまでのviewの部分も内包されているんだけど、そこが分離できるとフロントエンドが得意な人にRubyのコードを触らずにフロントエンドのほうで便利な機能を実装してもらいやすくなるかなあ、っていう。

基本的に他力本願なところがあり他人のちからを借りやすくなるような変更を入れていきたい次第

まあ「GraphQL実装したい」じゃなくて「GraphQL実装しました」報告がしたいところですが当面は引っ越しに集中しています。(まだ荷物の移動が終わっていない)


鼻水が出ていてシャワーをさぼったり耳たぶをいじっていたらピアスホールから出た汁が固まっていて「なるほど」という感じ、完成は遠い。

2020-07-14 にっき

自分はアヒルのように動けばアヒル、Arrayを拡張して回転寿司のように動くArrayは回転寿司、そういう雑な気持ちでRefinementsを使っているんだなあ。べんりなので...。

これは雑すぎですがこういう感じ

「こうでもかけるんだけど〜」とクラスを定義しだすと「クラスでいいじゃん」になるかと思いますがクラスを定義しなくていいというのが便利ポイントなのでその辺の音楽性の違いっぽい。 あとは同じことをやるならメソッドにしなくてもよくて結果を説明的な名前の変数名に入れればいいのでは、とかもありそうだけど、それもやはりすごく特定のユースケースに合わせたメソッドをその場だけで使うことが出来る、というところに価値を見出しているんですよね。 一般的なメソッドを組み合わせて呼びたいわけじゃなくて特定のユースケースに合わせて作ったメソッドが生えているのがよい。 そういう意味でいうと自分はやはり語彙を再定義しているRSpecみたいなところをRubyの書きはじめの最初にガツンとうけてしまったので文化的な背景がやはり違いそう。


色々と話していてrefine(Array) よりも refine(sushi.singleton_class) のほうがより範囲が狭くなって Module.new との相性がよいことに気がついた。


これの感想にリプ返していた

hanachin.hateblo.jp

雑ではない仲間

雑仲間

アプリケーションの中でライブラリみたいなことをやるときに補助的なAPIを完全にprivateなものとしてはやせるのはやはり便利そう

これもそうかな

いい話!なので特にリプをしていなかった

雑仲間だ

なんでなんだろうなあ

この辺を読み直しているけど使ってみるとやっぱり削がれてしまった機能をもとめてブロック単位のRefinementsとかを作り出してしまうので使い勝手がよくないだけなんだろうか

magazine.rubyist.net rubykaigi.org github.com

組み込みを拡張したいとなるとそうですよね、という感じ

はい

Refinementsの用法用量わからない日記

自分はわりとカジュアルにRefinementsを使うけど基準はどこにあるのだろう。と今日考えていた。

RefinementsSpecを読んでみる

はい

Monkey patching is a powerful feature of Ruby.However, it affects globally in a program. Therefore, a monkey patch might break code which doesn't expect the extended behavior, and multiple monkey patches for the same class might cause conflicts.To solve these problems, Refinements provide a way to extend classes locally. https://bugs.ruby-lang.org/projects/ruby-master/wiki/RefinementsSpec

モンキーパッチはRubyの強力な機能の1つ。しかしながら、モンキーパッチはプログラムにグローバルに影響を与える。したがって、モンキーパッチはモンキーパッチにより拡張された振る舞いを予期していないコードを壊す可能性があり、また一つのクラスに対して複数のモンキーパッチを当てるとコンフリクトを引き起こすかもしれない。これらの問題を解決するため、Refinementsはクラスを局所的に拡張する方法を提供する。

みたいな感じ?

局所的に、というのがキモっぽい

クラスの動作を拡張したいが局所的にしたい、というのが大事っぽい。 具体的にはどういうときなのか判断はわりとグラデーションがあると思う。

アプリケーションコードにおいて局所的に拡張する必要性

実はほとんどないのでは、と思う。

例えばアプリケーションのコードの動作を拡張したい場合

「アプリケーションコードの動作を拡張したい!」 「じゃあアプリケーションコードを書き換えようか (完)」

はい。

「局所的にアプリケーションの動作を拡張したい!」 「じゃあそういう設計でアプリケーションコードを書き換えようか (完)」

はい。

となりますよね。

現代のモンキーパッチはオープンクラスをせずにできる

モンキーパッチをどういうときに用いるかというと

  • 組み込みライブラリの動作を変更したい
  • gemで導入したライブラリの動作を変更したい

などアプリケーションコードとは違う自らが書き換えできないコードをダイナミックに書き換えるときだと思う。 じゃあそれモンキーパッチじゃないとできないの?というと現代だとそんなことはない。 例えば書き換えたgemをGitHubに置いてGemfileでgitリポジトリを指定すれば済む。

だがそれだともちろん局所性はない。

オープンクラスが必要な場面

やっぱり自分の手が届かないところのコードの動作を書き換えるときかなあ。(自分が書いてるのはだいたいそう)

局所性が必要な場面とは

例えば同じ名前のメソッドが被ると困るだろう。 でも現実問題アプリケーションコードのためにモンキーパッチで拡張したときに困るのって、既にあるメソッドの名前と同じ名前で書き換えたときぐらいしかなさそう。 別の名前のメソッドを追加して動作を拡張するのはまあ、名前がかぶれば変えればいいだけなので。

多分ライブラリを書いている場合は、ライブラリが使われる場面には手が届かないのでより局所性に気を使う必要がありそう、なのでRefinementsの使いどころはアプリケーションコードよりはありそう。

局所性を求めるとやっぱりRefinements、だが真に必要な場面は

局所性を求めるとRefinements、これは多分異論ないと思う。

だけど真にRefinementsでしか実現しないような使いどころとなるとかなり限られてしまいそう。

  • アプリケーションコードではないライブラリの動作を拡張している
  • アプリケーションコードの方の設計を変えられない
  • ライブラリの方で定義されているメソッドの動作を変えるので局所性が必要
  • 自分のコードがどこで使われるか分からないので自分のコード内だけで使う動作に局所性が必要

アプリケーションからは変更出来ないコードを変更したいが影響範囲を狭めたい、そのぐらいしかなさそうで。ほかはアプリケーションコード変えればいいだけだから。

アプリケーションのコードなのかライブラリのコードなのかの境界はどこにあるのか

例えばDeviseのモジュールを例にすると、Deviseのモジュールを使っているクラスにはDeviseのモジュール由来のメソッドがいくつか生える。

このときDeviseによって生えたメソッドを利用し、アプリケーション固有のユースケースを実現するコードはアプリケーションコードだと思える。 一方「この機能はDeviseの方でも持っていてほしいなあ、わりと特殊なユースケースかもしれないけど」と思うコードや「これはDeviseと組み合わせて使えるライブラリに出来るコードかもしれないなあ」というコードもあると思う。 それはアプリケーション固有の事情を表していないので純粋に単なるアプリケーションコードとしてしまうにはもったいない。

十分一般的な目的に抽象化されたアプリケーションコードはそれはもうライブラリなのでは、と思ってしまう。

Refinementsの使いどころにアプリケーションコードとライブラリの境目も含めてしまってよいのでは

そういう本来ならこのメソッドはライブラリに置かれててくれどうぞ、みたいな気持ちとRefinementsは相性いいと思うんですよね。

特定の場面でしか発生しないようなユースケースも十分抽象化されていたら実質ライブラリなのでは

例えば大クラス主義的にArrayに色々生えてて日常生活ではことたりるんだけど、たまーに「アプリケーション固有かもしれないけど each_with_いろは がほしい」とかあると思うんですよ。 それもわりとアプリケーション固有なのかライブラリなのか微妙な立ち位置で、Refinementsがはまると思うんですよね。

関連レコードを引くとかscope使いたいとかそういうActiveRecordの機能によるのはactive_typeのようなgemを使ってやると思うけど、 単純にこの場面でだけだけメソッド生やしたいとかならRefinementsで生やすだけでも十分みたいなの結構あると思うんですよね。

Refinements使うのを気をつけたほうがよい場合

めちゃくちゃパフォーマンス気にする場合はRefinements使わない方がいいのかなあというふわっとした感想です。(要出典、ここはFUDになりそうなので書かないほうがよかったかもしれない)

動的にメソッドの動作を切り替えたい場合にもRefinementsは便利

無名クラスでもできるかもしれませんが #to_refinements メソッドでRefinementsのモジュールを生成するようなコードを書くと using object.to_refinements で動的に動作を切り替えられて便利そうです。

rakeタスク中の処理を読みやすくメソッドにわけたいときもRefinementsは便利

これに関してはモデルにうつしたほうがテストしやすいのでいい派が多分いると思います

qiita.com

これも特定のユースケースの場合のみ機能を拡張したい場合の1つかなあ 通常のアプリケーションコードの中では使われてほしくないけどrakeタスクの中だけではメソッドであってほしい、そういう気持ち。

何かを受け流すときにもRefinementsを使うと便利

例えばRuboCopで定数のfreezeを呼びたいけどどうしてもテストではfreezeされてると都合が悪いとき、とか。

以外と真に必要そうなケースあるな

用法用量所感

どうしてもRefinementsじゃないとダメ!となる前にアプリケーションコードの変更でどうにかなってしまう場合が多い。 なのでそういうどうしようもない場合にのみRefinementsの処方を限定するとRefinementsを使う機会がかなり減ってしまうと思う。

アプリケーションコードなのかライブラリなのか曖昧な、アプリケーション固有のユースケースのようなそうでないような、ライブラリに置かれててくれどうぞ、みたいな気持ちとRefinementsは相性がいいと思う。

まとめ

ハチャメチャにRefinementsキメましょう

2020-07-12

生活を整えるためにカーテンとワードロープと姿見と床マットなどなどを見ていた

カーテンはとりあえず窓が増えた分を買わねばなない。 あまっているカーテン情報があったので、あまってるカーテン情報を貰ってから買う。 サイズ的には既成品で足りそうな見通しなので、サイズが合わなかったらポンとかえばよさそうな感じ。 遮音遮熱遮光防炎を選ぶとぐっと選択肢が狭まって便利。

ワードロープは鏡がついているしっかりしたタイプだと鏡が割れたときに補修が面倒そうということで安いパイプ + カバーみたいなタイプのと姿見を別で買うことにする。 しかし鏡の店頭在庫が全然なくて厳しい気持ち。

床マットに関してはニトリの店頭でクッションマットを見ていたけど結局マットを敷いて変わるか変わらないかは下に知り合いでも住んでいない限りわからない、二階ある家に自分たちで住んでみると実験できるかもしれないが。 そして店頭で防音と書かれていても商品の説明に防音と書いてある種類は結構少ない。 クッションマットに関しては水こぼすとつるっとすべってコケリスクが++みたいな説明があった。

クッションマット: 安い、広範囲をカバー出来る、すべる、ださい、あつそう、取り替えが省スペースだけ出来る 防音ラグ: クッションまっとよりは高い、広範囲をカバーできる、すべらない、ださくない、あつそう、取り替えが一部だけはできない(小便耐性が低い) フロアに敷くウッドカーペット的なもの: 防音なさそう、多分一番高い、取り替え一部一応できそう、小便耐性はわりと高そう

みたいな感想で、まあ敷くならラグかな...という感じがする


rbsからtsはくやつの雑なgem化していた

rbs 0.6.0にあげたりしていたら動かなくなっていた

typing_options :strict つけているときのリレーション周りの型がうまく通し方がわからない

このへんはこうでよさそう

module ActiveRecord::AttributeMethods::PrimaryKey
  attr_accessor id (): Integer
end

class ActiveRecord::Base
  extend ActiveRecord::AttributeMethods::PrimaryKey
end

class ActiveRecord::AttributeMethods::GeneratedAttributeMethods
end

class Board < Board::GeneratedAttributeMethods
end

class Board < Board::GeneratedAttributeMethods
  class GeneratedAttributeMethods < ApplicationRecord
  end
end

interface _ActiveRecord_Relation_ClassMethods[Model, Relation] が難しいきがする

class Board < Board::GeneratedAttributeMethods
  extend _ActiveRecord_Relation_ClassMethods[Board, Board::ActiveRecord_Relation]
end

するとこうなる

app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.all (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.ids (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.none (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.pluck (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.where (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.exists? (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.order (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.group (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.distinct (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.or (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.merge (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.joins (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.left_joins (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.left_outer_joins (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.includes (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.eager_load (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.preload (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.find_by (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.find_by! (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.find (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.first (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.last (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.find_each (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.find_in_batches (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.destroy_all (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.delete_all (class Board < ApplicationRecord)
app/models/board.rb:1:0: MethodDefinitionMissing: module=::Board, method=self.update_all (class Board < ApplicationRecord)

どうしたらいいんだろ

2020-07-11

転居に向けて整えていた。三ツ口コンロが待ち遠しい。


カーテンレール、シングルの物件にいまだ住んだことがなかったが、どうしよう。 レースカーテンって結局レース部分をあけることがほぼないので突っ張り棒とかで布でも垂らそうかな。


生活をしていると様々な物事を考えなくてよくなるのでべんり。暮らしは大事。


YubiKeyが届いたけど耳から垂らすには結構なでかさであり、及び腰になる


ピアッサーでついたファーストピアス、前後への移動がかなりスルスルいくようになっていて内部で何かしらの変化が起きていそうなのを感じる。


新居のベランダについて隙間から子どもがはみ出ないか調べていた。結論はみ出る。 どうやって防御するといいのだろうか、ベランダって自分の敷地じゃなくて共用スペースだからあんまりものとかを設置したくないではある。 網かけるぐらいかなあ。


久しぶりに県立図書館へ行って鉄道の本を借りてきた。子が真の踏切を見たがる頃までLCC続いてコロナ終わっててほしい。

いいなと思ったらKyashでお金を下さい
20191128011151
GitHubスポンサーも受け付けています
https://github.com/sponsors/hanachin/