ESM アジャイル事業部 開発者ブログ

永和システムマネジメント アジャイル事業部の開発者ブログです。

Kaigi on Rails 2024にswamp09が登壇します

2024年10月25日 (金) から 10月26日 (土) に東京の有明で開催される『Kaigi on Rails 2024』の2日目 (10月26日) に弊社から @swamp09 が登壇します。

kaigionrails.org

ここでは、登壇者の @swamp09 から講演内容について軽く紹介をします。

Hall Blue: 14:10~14:25 Importmapを使ったJavaScriptの読み込みとブラウザアドオンの影響 (@swamp09)

私 (@swamp09) が参加しているプロジェクトでは、HotwireやImportmapを使用してRailsアプリ開発を行っています。 Importmapをproductionで使っていてブラウザ上でJavaScript読み込みの失敗に直面した実際の事例を元に、問題の発見から解決に至るまでのプロセスを解説します。 また、Rails 7でデフォルトとなったImportmapを使ったJavaScriptライブラリの動的インポートについて、従来のJSバンドル手法との違い、利点について紹介します。

Importmapってなんだっけ?と気になっている方や、実際に使ってみてどういう問題に直面するのか興味がある方に向けた内容です。


現地チケットは限りあるようで、早めの入手をされると良さそうです。なお、オンラインチケットは無料で販売されているようです。

ti.to

また、弊社永和システムマネジメントは Gold Sponsor として関わっており、9人のメンバーが現地参加予定です。Kaigi on Rails 2024 でお会いしましょう。


永和システムマネジメントでは、Ruby とアジャイルソフトウェア開発を通じてコミュニティと成長したいエンジニアを絶賛募集しています。

agile.esm.co.jp

TokyuRuby会議15にjunk0612が登壇します

2024年9月29日(土) に開催される TokyuRuby会議15 に永和システムマネジメントから junk0612 が登壇します。

tokyurubykaigi.github.io

今回は、登壇内容について少しご紹介します。

junk0612 『LR で JSON パーサーを作る 第2回』

junk0612 です。TokyuRuby会議15では『LR で JSON パーサーを作る 第2回』というタイトルで話をします。

「第2回ってどういうこと?」と思う方がいるかもしれません。先日の大阪Ruby会議04 (登壇記事はこちら) にて、スポンサーLTとして『LR で JSON パーサーを作る』という発表をしており、このときは某料理番組風に LR を採用した JSON パーサーを3分で作る発表をしました。

スポンサー LT らしくない内容からか参加者にも好評だったので、発表内に次回予告として入れてあった構文木の生成を行う内容をスピンオフとしてやってしまおうという趣旨の……

えっ!? 「アレ」できたの!? じゃあこうしちゃいられない!すぐに準備しないと!!

※番組内容は変更になる可能性があります。あらかじめご了承ください。


TokyuRuby会議15 はすでに満席になっておりますが、順番待ちで繰り上がりの可能性があるかもしません。お楽しみに!

tokyurb.connpass.com


永和システムマネジメントでは、Ruby とアジャイルソフトウェア開発を通じてコミュニティと成長したいエンジニアを絶賛募集しています。

agile.esm.co.jp

Rails / OSS パッチ会 2024年9月のお知らせ

2024年9月の Rails / OSS パッチ会を 9月30日(月)に Discord でオンライン開催します。

この会をひとことでいうと、日頃のお仕事で使っている Rails をはじめとする OSS について、upstream にパッチを送る会です。

会には Ruby と Rails のコミッターである顧問の a_matsuda もいますので、例えば Rails に送るパッチのネタがあるけれど、パッチを送るに適しているかの判断やパッチを送る流れが悩ましいときなど a_matsuda に相談して足がかりにするなどできます。

開催時間は 17:00-19:00 となりますがご都合のあう方はぜひご参加下さい。

Discord の Rails/OSS パッチ会サーバーへの招待 URL は以下です。

discord.gg

Rails World 2024 でリリースされた Rails 8.0.0.beta1 や、来月開催される Kaigi on Rails 2024 について話題にしながらの開催になると思います。

kaigionrails.org

これからパッチ会に参加してみたいという方、OSS 開発者間の会話に興味があるので聞いてみたいという方もお気軽にどうぞ。


永和システムマネジメントでは、Ruby とアジャイルソフトウェア開発を通じてコミュニティと成長したいエンジニアを絶賛募集しています。

agile.esm.co.jp

Kaigi on Rails 2024 に Gold Sponsor として協賛します

株式会社永和システムマネジメントは、2024年10月25日(金)から26日(土)にかけて東京の有明で開催される、Kaigi on Rails 2024 に Gold Sponsor として協賛します。

kaigionrails.org

また、熾烈な CFP プロポーザル採択の門を突破した、弊社 Rails アプリケーション開発者が、現場からのテクニカルな実践テーマで登壇します。タイムテーブルの公開まで乞うご期待。

チケットを購入して続報への待機をしつつ、現地参加者の皆さんと有明でお会いしましょう。


永和システムマネジメントでは、Ruby とアジャイルソフトウェア開発を通じてコミュニティと成長したいエンジニアを絶賛募集しています。

agile.esm.co.jp

Elixirメタプログラミングで書く、関数っぽい関数でない何か

今回の Elixir のお題には、メタプログラミングを選んでみました。

Elixir に限らずメタプログラミングでは、ふだん関数を書くときとは異なるレベルの視点が要求されます。

今回は、関数のように見えるけれど関数でないものをメタプログラミングで表現してみましょう。

例題

例として。 利用者 (User) が、記事 (Article) の読み書き削除の操作を可能かどうか、可否の判定をする仕組みを考えます。

読み書き削除の操作の可否は、次のように定義することにしました。

  • 任意の User は Article を読むことができる
  • User が Article の所有者、もしくはロールが editor の User のばあいは、Article に書き込むことができる
  • User が Article の所有者のばあいは、Article を削除することができる
  • それ以外の操作はできない

これをコードで表現していきます。

プログラミング Elixir

まず、利用者 User と記事 Article を表現する構造体を定義します。

User には、ID とロールを持たせます。

defmodule User do
  defstruct [:id, :role]
end

Article は、所有者を識別するオーナ ID と内容を持つものとします。

defmodule Article do
  defstruct [:owner_id, :content]
end

これらの構造体に対し、操作の判定をする関数は次のように定義しました。

操作は、第 3 引数のアトム(Ruby で言うところのシンボル)で指定しています。

defmodule Permission do
  def permitted?(%User{},              %Article{},             :read  ), do: true  # 任意のユーザは読み込み可能
  def permitted?(%User{role: :editor}, %Article{},             :write ), do: true  # 編集者は書き込み可能
  def permitted?(%User{id: id},        %Article{owner_id: id}, :write ), do: true  # 所有者は書き込み可能
  def permitted?(%User{id: id},        %Article{owner_id: id}, :delete), do: true  # 所有者は削除可能
  def permitted?(%User{},              %Article{},             _      ), do: false # それ以外の操作は不可
end

ちなみに、%User{id: 123, role: :editor} という表記は、Elixir の構造体のデータ表現です。

試してみましょう。

User が所有者のばあいは、すべての操作が可能です。

article = %Article{owner_id: 123}
user = %User{id: 123}

Permission.permitted?(user, article, :read)   #=> true
Permission.permitted?(user, article, :write)  #=> true
Permission.permitted?(user, article, :delete) #=> true

所有者でなくても、ロールが editor のばあいは read, write が可能です。 しかし delete はできません。

article = %Article{owner_id: 123}
user = %User{id: 456, role: :editor}

Permission.permitted?(user, article, :read)   #=> true
Permission.permitted?(user, article, :write)  #=> true
Permission.permitted?(user, article, :delete) #=> false

それ以外の User は、read は可能ですが、write, delete はできません。

article = %Article{owner_id: 123}
user = %User{id: 789}

Permission.permitted?(user, article, :read)    #=> true
Permission.permitted?(user, article, :write)   #=> false
Permission.permitted?(user, article, :delete)  #=> false

ここまでが普通の Elixir プログラミング。

これより先がメタプログラミングの世界です。

メタプログラミング Elixir

Elixir のメタプログラミングは、マクロという仕組みを利用します。

マクロを読む

普通の関数が入力として値を受け取り出力として値を返すのに対し、マクロは入力としてプログラムを受け取り出力としてプログラムを返す仕組みと言えます。

このときの入力と出力は、いわゆる AST (Abstract Syntax Tree) で表現されています。

たとえば文字列を出力する次のコードは、

IO.puts("Hi!")

このような表現になります。

{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [], ["Hi!"]}

(実際には、メタデータとしてファイル内の行番号などの情報が付加されるので、これとまったく同じ表現になるわけではないのですが、プログラム構造の部分のみを抜き出した骨格はこれと同じ形になります)

これを返すマクロを書いてみます。

defmodule Greeting do
  # 関数を定義する def ではなく、マクロを定義する defmacro を使う
  defmacro hi do
    {{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [], ["Hi!"]}
  end
end

マクロを有効にするには、モジュールを require もしくは import します。

require Greeting
Greeting.hi()

Greeting.hi() の戻り値は IO.puts("Hi!") の AST でしたので、結果として IO.puts("Hi!") が実行されます。 実行するとコンソールに Hi! と表示されると思います。

import するとモジュール名の修飾が不要になるので呼び出しが少し簡単になりますが、名前の衝突には気をつけてください。

import Greeting
hi()

マクロを使うとコードを差し込めることは分かりました。 しかし人の力で AST の表現のデータを記述するのは大変です。

そこで quote を利用します。

quote は、Elixir のコードを AST の表現に変換してくれます。

quote do
  IO.puts("Hi!")
end
#=> {{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [], ["Hi!"]}

また quote の中で unquote を利用すると、渡した変数を、変数の AST の表現でなく、変数の値として解釈してくれます。

quote do
  IO.puts(message)
end
#=> {{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [], [{:message, [], Elixir}]}
# 「変数 message」として扱われる

message = "Hello"
quote do
  IO.puts(unquote(message))
end
#=> {{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [], ["Hello"]}
# 変数 message の値の「"Hello"」として扱われる

戻り値だけでなく、マクロの引数も AST の表現になっています。 マクロの引数の中で関数呼び出しを書くと、マクロは関数呼び出しの AST 表現を受け取ることになります。

article = %Article{owner_id: 123}
quote do
  read(unquote(article))
end
#=> {:read, [], [%Article{owner_id: 123, content: nil}]}

マクロの引数で「関数呼び出し」を受けると、マクロの中では「関数名」と「その関数の引数」に分解して利用できるわけです。

「関数名」がただの値になるなら、それを引数として関数を呼び出すことも可能なはずです。

これらを踏まえて。 can?(user, read(article)) と書くと permitted?(user, article, :read) が実行されるマクロを書いてみましょう。

マクロを書く

Permission モジュールに can? マクロを追加します。

defmodule Permission do
  # permitted? 関数の定義は同じなので省略

  defmacro can?(user, {action, _metadata, [article]}) do
    quote do
      Permission.permitted?(unquote(user), unquote(article), unquote(action))
    end
  end
end

第 2 引数では「関数呼び出し」の AST を、関数名とメタデータと関数の引数に分解してして受け取ります。 ここではメタデータは利用しません。

分解した関数名と引数を Permission.permitted? の第 3 引数、第 2 引数に渡します。 このとき、「変数」ではなく「変数の値」を渡したいので unquote することを忘れてはいけません。

使ってみましょう。

import Permission

owner = %User{id: 123}
editor = %User{id: 456, role: :editor}
another_user = %User{id: 789}

article = %Article{owner_id: 123}

can?(owner, read(article))   #=> true
can?(owner, write(article))  #=> true
can?(owner, delete(article)) #=> true

can?(editor, read(article))   #=> true
can?(editor, write(article))  #=> true
can?(editor, delete(article)) #=> false

can?(another_user, read(article))   #=> true
can?(another_user, write(article))  #=> false
can?(another_user, delete(article)) #=> false

ここで readwritedelete といった関数は定義されていないことに注目です。 can? の第 2 引数は、「関数を呼び出した結果の値」ではなく「関数呼び出し」そのものなので、呼び出す関数自体の定義は必要ないからです。

また Elixir は、次のような関数呼び出しを、

func(arg1, arg2)

パイプ演算子 |> を使ってこのように記述することができます。

arg1 |> func(arg2)

そうすると、こんな表現も可能です。

クエスチョンマークの位置や括弧の存在が惜しいところですが。

if user |> can?(write(article)) do
  # do something
end

実は。 この仕組みのアイディアは、Elixir の Canada というパッケージから拝借しています。

github.com

Canada ではマクロの他にプロトコルという仕組みも利用していて、より柔軟に適用することができるようになっています。

そしてコードを読んで、記述できる表現に対してそのコードのコンパクトさに驚いてみてください。

ご注意

メタプログラミングは用法用量を守ることが必須です。 くれぐれも過剰摂取にはご注意を。

物以類聚

プログラムをメタプログラミングする行為には、不思議な魅力があります。

普通のプログラミングだけでは物足りないと感じている方、プログラムをメタプログラミングしたい方、プログラミング言語をプログラミングしたいと感じている方。 同志を探しに来てみませんか?

agile.esm.co.jp

福岡Rubyist会議04に永和システムマネジメントからhtkymtks, shun_hiraoka, maimuの3人が登壇します

2024年9月7日(土) に開催される 福岡Rubyist会議04 に永和システムマネジメントから htkymtks, shun_hiraoka, maimu の3人が登壇します。

regional.rubykaigi.org

ここでは、それぞれの登壇者から講演内容について軽く紹介をします。

11:40-12:05 htkymtks 『Building a Ruby-like Language Compiler with Ruby』

はたけやま(@htkymtks)です。

この発表では、Rubyライクな小さな言語「TinyRuby」のコンパイラ開発を題材に、コンパイラ作成の基礎と実践的なテクニックを紹介します。アセンブリが全く分からない方でも、コンパイラを作れるようになるためのポイントを解説しますので、コンパイラを書いてみたい方や、低レイヤーの技術を深く理解したい方はぜひ聞きに来てください。

13:30-13:55 shun_hiraoka 『Trying to Make Ruby's Parser Available as a Gem』

こんにちは、構文解析器研究部員のS.H.です。

今回僕は「Trying to Make Ruby's Parser Available as a Gem」というタイトルで発表します。 内容としては、CRubyのUniversal ParserをC拡張のgemとして実装し、Rubyから利用できるようにするというものです。

現在、CRubyにはUniversal Parserとしてparse.yほかいくつかのソースコードを利用できるようになっています。 ただ、実際にそれらを使ってRubyのコードをパースさせるというgemはほとんどありません。

そこでプロトタイプ的にCRubyのUniversal ParserをC拡張のgemとしてRubyから利用できるようにしてみたいと思いました。 登壇駆動開発で現在頑張って実装しており、当日動くものをぜひお見せしたいと思います。

14:00-14:25 maimu / Chie 『Rails Girls is My Gate to Join the Ruby Community』

こんにちは!maimuです。

私はRails Girls Fukuoka 3rdのオーガナイザーを務めたChieさんの発表後に「Rails Girls is My Gate to Join the Ruby Community」というタイトルで発表します。

今回はRails Girlsをきっかけに偶然の出来事の繋がりに自分なりに意味を見出して、それを自分自身の原動力にしながらコミュニティも仕事も楽しんで取り組んでいる日々についてを話したいと思っています。

私は2022年12月に開催されたRails Girls Gathering Japan 2022にLT登壇したこと・初めて懇親会に参加したことをきっかけにRubyコミュニティに少しずつ参加するようになりました。 その後、Rails Girlsガイドの翻訳をたくさんの方の協力を得て進めたり、その取り組みを地域Ruby会議でLT発表したことで東京でRails Girlsを開催しようというモチベーションが生まれたり、実際にRails Girls Tokyo16thのオーガナイザーを務めたりとRails Girlsをきっかけに、Rubyコミュニティでの輪が広がっていき、さらに自分自身の取り組みの幅も広がっていきました。

コミュニティに参加したての方やこれから参加してみたいと考えている方にぜひ聞いていただけると嬉しいです。


また 14:30-15:30 の枠では、永和システムマネジメント アジャイル事業部の顧問でもある kakutania_matsuda がパネルディスカッションに参加します。

福岡Rubyist会議04は本編、懇親会とも絶賛参加受付されています。

fukuokarb.connpass.com

fukuokarb.connpass.com

各メンバーの発表をお楽しみに!

福岡Rubyist会議04の登壇者が所属する永和システムマネジメントでは、Ruby とアジャイルソフトウェア開発を通じてコミュニティと成長したいエンジニアを絶賛募集しています。

agile.esm.co.jp

中高生国際Rubyプログラミングコンテスト2024に今年も協賛します

@junk0612 です。これからの社会を担う世代を対象にした Ruby のプログラミングコンテスト、『中高生国際Rubyプログラミングコンテスト2024 in Mitaka』に、今年も Gold PARTNER として協賛します。

www.ruby-procon.net

毎年さまざまなアイディア・工夫を凝らした作品が提出され、創ったみなさんによる熱のこもったプレゼンが行われるので、どちらもすでに楽しみです。 最終審査会に今年もお邪魔する予定です。どうぞよろしくお願いいたします。

アジャイルと Ruby が実現するソフトウェア開発は、開発者が「楽しさ」を感じられる開発であり、そこにはきっとビジネス価値がある――私たちはそう信じて行動を続けています。同じように、プログラミングを楽しくする Ruby を通じて実現される、中高生の作品を楽しみにしています!


株式会社永和システムマネジメントでは、Ruby とアジャイルソフトウェア開発を通じてコミュニティと共生しながら成長したいエンジニアを絶賛募集しています。

agile.esm.co.jp