RubyVM::AbstractSyntaxTree で Node を辿る処理をシンプルに実装する

Ruby の Enumerator を使うと簡単にRubyのコードを処理できて便利だったので、ブログに書いておく。 ast = RubyVM::AbstractSyntaxTree.parse(<<~RUBY) class User < ApplicationRecord def say(text) puts text end def sum(x, y) x + y end end RUBY enum …

【追記】Rails v7.1.0 で `can't be blank` が `can’t be blank` に変わる(リバートされました)

既存アプリやライブラリへの影響が大きく、この変更に対してネガティブなフィードバックも多かったためリバートされました。 github.com 概要 表題の通り、Rails v7.1.0 で APOSTROPHE (U+0027) が SINGLE QUOTATION MARK (U+2019) に変わります。 github.co…

プルリクで更新されたgemの一覧を出力する

Gemfile.lock のdiffから更新されたgemを探す方法を調べたのでメモ 動作確認に使ったプルリク github.com GitHub APIでプルリクの情報を取得する $ gh api '/repos/rails/rails/pulls/48955' --jq '.base.sha, .head.sha' 1e824aa8e0655b4717cf612e31010bdd8…

Rubyやgit-gsubを使って正規表現で複数行を置換する part2

sinsoku.hatenablog.com の続き。 回答 3 Rubyで -0777 を指定するとファイル単位で読み込む方法を教えて頂きました。 $ cat foo.txt foo $ cat bar.txt bar $ cat buz.txt foo bar buz $ ruby -i -n0777 -e 'puts "hi, " + $_' foo.txt bar.txt buz.txt $ c…

Rubyやgit-gsubを使って正規表現で複数行を置換する

150個を超える *.tf をまとめて編集する方法を調べたので、備忘録としてまとめておく。 経緯 Terraformのコードを複数ファイルにすべきか、それとも1つのファイルにすべきか難しいな。hclをパースして、hclを書くプログラムを書いた方が良いのかなぁ...— 神…

手元にあるパッチの一覧を確認するシェルスクリプト

git

ブログに書いていなかったことに気づいたので、残しておく。 モチベーション OSSや仕事のコードを修正してるときに「まだ動作確認ができていない」「コミットメッセージの説明が不十分」なコミットが手元に溜まることがある。 このパッチの一覧を確認するた…

Railsの DATABASE_URL で指定できるパスワードの文字種

Railsアプリケーションを動かすAWSリソースをTerraformで作る場合、random_password を使ってDBパスワードを生成します。 しかし、 DBパスワードに一部の記号が含まれていると環境変数 DATABASE_URL で渡す際に URI::InvalidURIError が発生してしまうため、…

GitHubのPull Requestでコミットメッセージの文字数を調べる

GitHubのPull Requestで各コミットメッセージの文字数や変更行数を取得する方法を調べたのでまとめておく。 GraphQL APIで取得できたので、雑にcsv形式にして出力した。 stat-commit-messages.sh #!/bin/bash set -eu OWNER=${1:-rails} NAME=${2:-rails} NU…

Rubyの定数の探索順序

Ruby技術者認定試験の勉強のため、この機会にちゃんと理解しておく。 バージョン $ ruby --version ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [arm64-darwin21] 継承 子クラスに定数がない場合、親クラスの定数を参照できる。 class A FOO = "foo" BA…

Rubyのフリップフロップ (flip-flop) 構文

Ruby技術者認定試験の勉強をしていて、初めて知った機能だったのでまとめておく。 Ruby長年やってるけど、条件式の範囲式とか初めて見た。5.times { (_1==2)..(_1==3) ? p(_1) : 0 } みたいなやつ。— 神速 (@sinsoku_listy) 2022年10月6日 公式ドキュメント …

Ruby 3.1.xだと継承ツリーに後からincludeでモジュールを追加できる

Ruby技術者認定試験Goldの勉強をしていてRubyのバージョンによって変わっている挙動を知ったのでメモ。 検証コード module M1 def method_1 __method__ end end class C include M1 end p C.new.method_1 module M2 def method_2 __method__ end end module …

Rubyのensure節の挙動

Ruby技術者認定試験の対象バージョンがRuby 3.1.xになったので、試験勉強していて気づいた挙動をブログにメモっておく。 ensure節の値は無視される ensure 節が存在する時は begin 式を終了する直前に必ず ensure 節の本体を評価します。 begin式全体の評価…

Rubyで1つのインスタンスに同名メソッドを複数保つ方法

きっかけ Swiftでprotocolの実装を複数持てるのは便利そうだなぁと思ったことある。(foo as A).call だとA#call で、(foo as B).callだとB#callが呼べる的な #fukabori_rubykaigi_2022— 神速 (@sinsoku_listy) 2022年10月5日 よく考えたら as メソッドを…

RubyのModule#includeで引数を複数指定すると逆順で追加される

Module#include は引数に複数のモジュールを受け取ることができる。 しかし、以下のサンプルコードで分かるように、モジュールの順序は3行で書いたものと逆になるので注意がいる。 module A; end module B; end module C; end class Foo include A include B…

課題管理に対する考え方とテンプレ

自分の中の課題管理に対する考え方を整理するため、ブログにまとめておく。 課題を管理する ソフトウェア開発ではGitHub IssueやRedmineなどで課題を管理する。 基本的に「課題を登録する量 >> 完了する量」であり、多くの課題が登録されるため、優先度をつ…

RustでRubyのgemを書く part2

RustでRubyのgemを書く part1 の続き。 クラスやインスタンス変数を使うメソッドを実装したので、まとめておく。 Rubyで実装したいコードのイメージ module Wasabi class Object def initialize(name) @name = name end attr_reader :name def say "say, #{n…

RustでRubyのgemを書く part1

RubyGems 3.3.11でRust拡張の対応が実験的に入ったので、少し触ってみたメモ。 In particular, it includes experimental supppot for Rust extensions. 引用: https://blog.rubygems.org/2022/04/07/3.3.11-released.html wasabi 2019年に鹿児島Ruby会議01…

RailsアプリをRBS + Steepで型チェックするまでの手順

rails new してから steep check が通るまでにやってみた作業をまとめておく。 GitHub コードはGitHubで公開しているので、詳細な手順を知りたい方は参照してください。 github.com 手順 gemを入れる steepとrbs_railsをGemfileに追加する。 # Gemfile group…

ディレクトリ構造にあわせてrbsのプロトタイプを生成するシェル

既存のリポジトリでrbsをゼロから書くのは大変なので、とりあえず雑にプロトタイプを生成する方法。 ディレクトリ構造 app 以下のディレクトリ構造にあわせて sig にrbsを置くディレクトリ構成です。 app/models/user.rb sig/app/models/user.rbs シェル fin…

ECSを運用で使っていて難しいと思った点

ECSを触っていて今まで難しいと思ったことを雑にまとめておく。 ECSを仕事で運用するときに必要な知識が多すぎる。こんなの社内に1人AWSマスターいないと無理だ...— 神速 (@sinsoku_listy) 2021年8月10日 タスクロールとタスク実行ロールの違い ECSを長く触…

Gemfileに記載してあるgemの説明を一覧で表示する #fjordbootcamp

追記: bundle info でgemの情報を表示できるので、一覧じゃなければコレで十分かも。 $ bundle info rails * rails (6.1.3.2) Summary: Full-stack web application framework. Homepage: https://rubyonrails.org Documentation: https://api.rubyonrails.o…

SlackのGitHub Appをアップグレードするとdeployコマンドと通知が壊れる

先日、SlackのGitHub Appがアップグレードされました。 github.com しかし、アップグレードすると /github deploy コマンドとデプロイ通知が 壊れる ため、業務で使っている場合はもう少し様子を見てからアップグレードした方が良さそうです。 READMEの記述 …

Rubyをインストールせず Docker だけを使ってrails newを実行する

rails new するときにDockerfileを使う必要は特にない。 むしろ開発時に使うDockerfileとは別物になるので、Dockerfileを作らない方が良いです。 コマンド $ mkdir example_app $ cd example_app $ docker run --rm -v $(pwd):/app -w /app ruby:3.0.0 bash …

Railsアプリの開発環境向けDockerfile + docker-compose.yml

人に説明するときに記事あると便利なので、開発環境向けのDockerfileとdocker-compose.ymlを書いておく。 Dockerfile FROM ruby:3.0.0 WORKDIR /app # Using Node.js v14.x(LTS) RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash - # Add packa…

assets:precompileの結果を1世代だけ残す

Sprocketsは assets:clean[0] しても1時間以内に作成したassetsは消してくれません。 参照: https://github.com/rails/sprockets/blob/v4.0.2/lib/sprockets/manifest.rb#L245 さらに assets:clean の後に webpacker:clean を実行してくれるけど、引数は伝搬…

Herokuでカスタムドメイン(ルートドメイン)を使うためにCloudFrontを設定する

Route53で取得したカスタムドメインをHerokuで使うためにCloudFrontの設定をしたのでブログに書いておく。 コード例は foo.herokuapp.com で動くアプリケーションを foo-example.com でアクセスできるようにする設定です。 AWS側の設定 CloudFrontで使うacm…

git-notesでコミットにメモをつける

git

2020年に「コミットログは良くならない」というのを悟ったので、現実的な解決案である「git-notesでメモを残す」について記事を書いておきます。 前回の記事 sinsoku.hatenablog.com git-notes 詳細は git notes --help を読んでください。 概要は以下の通り…

Gitのプルリク(ブランチ)単位でログを追う方法

git

過去に「よいコミットメッセージとは」みたいな記事を書いたこともある。 sinsoku.hatenablog.com なぜコミットメッセージは良くならないのか どうしたらGitのコミットメッセージが良くなるか考えてみたけど、 他人に期待するには無理がある という結論に至…

CIでRailsのmasterブランチを使ってテストを実行する

Rails edgeでCIを動かしたい酔狂な人向けに記事を書いておく。 Rails edgeのGemfileを用意する # gemfiles/rails_61.gemfile eval_gemfile File.expand_path('../Gemfile', __dir__) dependencies.delete_if { |d| d.name == 'rails' } gem 'rails', github:…

gemでVERSION定数が定義されていない場合にgemのバージョンを取得する方法

ときどきVERSIONの定義されていないgemに遭遇するので、備忘録として書いておく。 VERSION の無いgem いくつかのパターンがある。 gemspecで文字列を直接指定しているケース database_rewinder.gemspec VERSION は定義してあるのに require されていないケー…