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

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

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

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

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

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

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

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

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

discord.gg

今後予定されている Rails 7.2 以降のリリースや、地域Ruby会議、Kaigi on Rails に思いを馳せながらという雰囲気になると思います。

rubykaigi.org

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


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

agile.esm.co.jp

大阪Ruby会議04に永和システムマネジメントから koic と haruguchi が登壇します

2024年8月24日(土) に開催される 大阪Ruby会議04 に永和システムマネジメントから @koic@haruguchi-yuma の2人が登壇します。

rubykansai.github.io

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

14:50-15:05 @haruguchi-yuma 『競技プログラミングでみる Ruby の豊かさ』

rubykansai.github.io

こんにちは、@haruguchiです。私は『競技プログラミングでみる Ruby の豊かさ』というタイトルで発表します。

今回のセッションでは、普段のWeb開発とは一味違った、競技プログラミングならではのクリエイティブで簡潔なコードの世界をご紹介します。

私は2年ほど競技プログラミングのコンテストに参加し続けています。その中で、Rubyの多様なシンタックスやメソッドに驚かされることが多々ありました。特に、普段のWeb開発ではあまり使用しないメソッドや、コードゴルフのような簡潔で難読なコード、可読性を多少犠牲にしても簡潔に記述するシンタックスなど、Rubyの豊かさを再発見しました。

対象者は、普段保守・拡張性に富んだ可読性の高いコードを書いてしまっているRubyistです。 ぜひ一緒に、競技プログラミングらしい、クスッと笑えるお行儀の悪い(保守・拡張性に乏しく一見読めない)コードを楽しみましょう。

15:25-15:55 @koic 『Minify Ruby Code』

rubykansai.github.io

@koic です。今回は『Minify Ruby Code』というタイトルで Ruby のコードについて話します。タイトルにあるように JavaScript などの Web リソースの世界ではポピュラーな minify をとおした Ruby コードの話です。

近年では ruby.wasm が登場し、WASM/WASI により Web ブラウザーに限らずエッジコンピューティングへの可能性が広がってきていると思います。また来年の RubyKaigi 2025 では TRICK 2025 が開催されることもあるように、日頃目指している「動作するきれいなコード」ではない「動作する奇妙なコード」「動作する難読化されたコード」などが知られています。

Ruby における minify は、明日からすぐに役立つ技術ではありませんが、昨今の Ruby コミュニティ事情において、これらのことから考えられるネットワーク転送コストの軽量化や、コードで遊ぶことについてを考えるきっかけに繋がるコンテンツの提供を考えています。

なお本トークは、キーノートの kaneko さんと hasumikin さん、チーフオーガナイザーの ydah さんにちなみ構文解析の話が基盤にあります。Ruby を通じたコードの楽しさを再発見できるよう準備中です。お楽しみに。


また永和システムマネジメントとしては、Premium スポンサーとして関わっており、弊社気鋭の構文解析器研究部部員でもある @junk0612 がスポンサー LT として 14:10-14:15 の枠で登壇します。

スポンサーブースでは Ask the Speakers、出張!構文解析器研究部、角谷フェローによる『研鑽Rubyプログラミング』手売り販売所といった企画を予定しています。あわせてご期待ください。

大阪Ruby会議04は絶賛参加受付されています。

rubykansai.doorkeeper.jp

それでは大阪 中之島の会場でお会いしましょう。

大阪Ruby会議04 に Premium スポンサーとしても参加している永和システムマネジメントでは、Ruby とアジャイルソフトウェア開発を通じてコミュニティと成長したいエンジニアを絶賛募集しています。

agile.esm.co.jp