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

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

Rails / OSS パッチ会 2025年4月 (オンライン開催) のお知らせ

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

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

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

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

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

discord.gg

今月開催の RubyKaigi 2025 に関する話題などあると思います。

rubykaigi.org

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


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

agile.esm.co.jp

ESM Drinkup at RubyKaigi 2025 の参加登録について🍻

こんにちは!maimuです。

本日は『ESM Drinkup at RubyKaigi 2025』の詳細と参加登録についてのご案内です。

RubyKaigi最終日の4月18日(金)の夜に、愛媛の地元食材をふんだんに使った郷土料理を提供する郷土料理 五志喜を貸切にしてのドリンクアップを開催します🍻

参加の募集人数は90名を予定しています。

まずは75名までの方を先着枠とし、先着終了後は15名分の枠を抽選とさせていただきます。もし参加登録開始後に先着枠を逃してしまった場合は、キャンセル待ちでお待ちください。

募集開始は、3月27日(木)の12時を予定しています。

募集開始の際は X の @rubyagile にて Doorkeeper のイベントページの URL を公開予定です。ぜひフォローして募集開始をお待ちください。

RubyKaigiの感想などたくさんお話ししてRubyistの皆様と交流できることを楽しみにしています!

それでは、参加登録開始まで今しばらくお待ちください🙏


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

agile.esm.co.jp

で、シリアライズについて(シリアライズとデシリアライズのはなし)。

In computing, serialization is the process of translating a data structure or object state into a format that can be stored or transmitted and reconstructed later.

The opposite operation, extracting a data structure from a series of bytes, is deserialization.

en.wikipedia.org

開発者ブログの主にネタプログラミング担当、e.mattsan です。

最近は。 開発している Rails アプリケーションがほぼ Web API サーバで、HTML をレンダリングするのではなく JSON にシリアライズするコードを書くことが多くなっています。

シリアライズとは言っても JSON への変換で、送る側も受ける側もただデータの集まりとして扱うので、構造が元のオブジェクトとかけ離れていない限り変換は難しいことはありません。

Wikipedia でシリアライズを調べると、逆操作としてデシリアイズが説明されています。 シリアライズには、単にオブジェクトを保存や送信が可能な状態にするというだけでなく、デシリアイズによって元のオブジェクトを復元できるようにする意味も含まれています。

このようにシリアライズとデシリアライズは、時間や(過去に保存したオブジェクトを取り出す)空間を(別のコンピュータが送信したオブジェクトを受け取る)超えてオブジェクトを伝えることができる手段です。

ところで。 デシリアライズって、意識してやったこと、ありますか?

Ruby でオブジェクトをシリアライズする

まずはシリアライズから始めてみましょう。

Rectangle, Circle, Triangle の三種類の図形クラスを定義して、これらをシリアライズしてみます。

それぞれのクラスには、自分のインスタンスを IO オブジェクトに出力する #write_to を定義しておきます。

以下、行を圧縮したいために綺麗でない書き方をしていますがご容赦を。

class Rectangle
  def initialize(x: 0, y: 0, width: 0, height: 0)
    @x, @y, @width, @height = x, y, width, height
  end

  def write_to(io)
    io.puts ['Rectangle', @x, @y, @width, @height].join(' ')
  end
end

class Circle
  def initialize(x: 0, y: 0, r: 0)
    @x, @y, @r = x, y, r
  end

  def write_to(io)
    io.puts ['Circle', @x, @y, @r].join(' ')
  end
end

class Triangle
  def initialize(x1: 0, y1: 0, x2: 0, y2: 0, x3: 0, y3: 0)
    @x1, @y1, @x2, @y2, @x3, @y3 = x1, y1, x2, y2, x3, y3
  end

  def write_to(io)
    io.puts ['Triangle', @x1, @y1, @x2, @y2, @x3, @y3].join(' ')
  end
end

このコードを shape.rb という名前でファイルに保存し、こんな感じでオブジェクトを出力します。

require_relative './shape'

shapes = []

shapes << Rectangle.new(x: 1, y: 2, width: 20, height: 10)
shapes << Circle.new(x: 1, y: 2, r: 10)
shapes << Triangle.new(x1: 1, y1: 1, x2: 5, y2: 1, x3: 3, y3: 3)

shapes.each do |shape|
  shape.write_to($stdout)
end
Rectangle 1 2 20 10
Circle 1 2 10
Triangle 1 1 5 1 3 3

メモリ上のオブジェクトを、再現に必要な情報をすべて含んだテキストに書き出しました。 ですのでこれも一つのシリアライズです。 少なくとも、人の目には元のオブジェクトを復元するために必要な情報は足りていそうです。

で、どのように復元するとよいでしょうか。

Ruby でオブジェクトをデシリアライズする、その1

文字列を空白で分割してトークンの集まりにして、図形を表す文字列が来たら続く数字を数値として読み込む、という単純なアイデアから始めます。

先の IO に出力したテキストが shapes.dat という名前のファイルに格納されているとして話を進めます。

$ cat shapes.dat
Rectangle 1 2 20 10
Circle 1 2 10
Triangle 1 1 5 1 3 3
require_relative './shape'

tokens = File.read('shapes.dat').split
shapes = []

until tokens.empty?
  case tokens.shift
  when 'Rectangle'
    shapes << Rectangle.new(tokens)

  when 'Circle'
    shapes << Circle.new(tokens)

  when 'Triangle'
    shapes << Triangle.new(tokens)
  end
end

shapes.each do |shape|
  shape.write_to($stdout)
end

各クラスもトークンの集まり tokens から値を読み込めるように拡張します。

class Rectangle
  def initialize(tokens = nil, x: 0, y: 0, width: 0, height: 0)
    @x, @y, @width, @height =
      if tokens.nil?
        [x, y, width, height]
      else
        [tokens.shift.to_i, tokens.shift.to_i, tokens.shift.to_i, tokens.shift.to_i]
      end
  end

  def write_to(io)
    io.puts ['Rectangle', @x, @y, @width, @height].join(' ')
  end
end

class Circle
  def initialize(tokens = nil, x: 0, y: 0, r: 0)
    @x, @y, @r =
      if tokens.nil?
        [x, y, r]
      else
        [tokens.shift.to_i, tokens.shift.to_i, tokens.shift.to_i]
      end
  end

  def write_to(io)
    io.puts ['Circle', @x, @y, @r].join(' ')
  end
end

class Triangle
  def initialize(tokens = nil, x1: 0, y1: 0, x2: 0, y2: 0, x3: 0, y3: 0)
    @x1, @y1, @x2, @y2, @x3, @y3 =
      if tokens.nil?
        [x1, y1, x2, y2, x3, y3]
      else
        [tokens.shift.to_i, tokens.shift.to_i, tokens.shift.to_i, tokens.shift.to_i, tokens.shift.to_i, tokens.shift.to_i]
      end
  end

  def write_to(io)
    io.puts ['Triangle', @x1, @y1, @x2, @y2, @x3, @y3].join(' ')
  end
end

オブジェクトの種類の識別をハードコードした、種類が増えるたびにコードを編集しなければならないよくある例です。

このハードコードした部分をどう解消するかが肝になりそうです。

Ruby でオブジェクトをデシリアライズする、その2

Ruby は、定義されているクラスを実行時に知ることができる言語です。 ですので、どのクラスが必要になるのかをプログラムでいちいち判定しなくても、実行している環境に問い合わせることができます。

Object.const_get('Rectangle')
#=> Rectangle

これでハードコードした部分を置き換えます。

require_relative './shape'

tokens = File.read('shapes.dat').split
shapes = []

until tokens.empty?
  class_name = tokens.shift
  shapes << Object.const_get(class_name).new(tokens)
end

shapes.each do |shape|
  shape.write_to($stdout)
end

便利。

自分が実行されている環境を、実行時に参照できる言語の利点です。

余談 - Ruby のマーシャリングとアンマーシャリング

このようなシリアライズとデシリアライズの機能は、実のところ Ruby にはマーシャリングという名前で標準装備されています。

docs.ruby-lang.org

rectangle = Rectangle.new(x: 1, y: 2, width: 20, height: 10)
#=> #<Rectangle:0x0000000136af1180 @height=10, @width=20, @x=1, @y=2>
data = Marshal.dump(rectangle)
#=> "\x04\bo:\x0ERectangle\t:\a@xi\x06:\a@yi\a:\v@widthi\x19:\f@heighti\x0F"
Marshal.load(data)
#=> #<Rectangle:0x00000001366b3708 @height=10, @width=20, @x=1, @y=2>

マーシャリングされたデータの形式もドキュメントにまとめられています。

docs.ruby-lang.org

dRuby は、マーシャリングの時空を超える能力を利用して実現されています。

docs.ruby-lang.org

C++ でオブジェクトをシリアライズする

かつてわたしが慣れ親しんでいた C++ ではどうでしょうか。

かつては慣れ親しんでいたもののしばらく触れていないため、書いたコードはいささか古臭いコードになっているかもしれません。 ご容赦を。

#ifndef SHAPE_HPP
#define SHAPE_HPP

#include <iosfwd>

class Shape {
public:
    virtual void write_to(std::ostream&) const = 0;
};

class Rectangle : public Shape {
public:
    Rectangle(int x, int y, int width, int height) : x(x), y(y), width(width), height(height) {}

    void write_to(std::ostream& out) const {
        out << "Rectangle " << x << " " << y << " " << width << " " << height << std::endl;
    }

private:
    int x;
    int y;
    int width;
    int height;
};

class Circle : public Shape {
public:
    Circle(int x, int y, int r) : x(x), y(y), r(r) {}

    void write_to(std::ostream& out) const {
        out << "Circle " << x << " " << y << " " << r << std::endl;
    }

private:
    int x;
    int y;
    int r;
};

class Triangle : public Shape {
public:
    Triangle(int x1, int y1, int x2, int y2, int x3, int y3) : x1(x1), y1(y1), x2(x2), y2(y2), x3(x3), y3(y3) {}

    void write_to(std::ostream& out) const {
        out << "Triangle " << x1 << " " << y1 << " " << x2 << " " << y2 << " " << x3 << " " << y3 << std::endl;
    }

private:
    int x1;
    int y1;
    int x2;
    int y2;
    int x3;
    int y3;
};

#endif//SHAPE_HPP

オブジェクトを生成してシリアライズするコードです。

#include <iostream>
#include <memory>
#include "shape.hpp"

typedef std::shared_ptr<Shape> shape_ptr;

int main(int, char**) {
    shape_ptr shapes[] = {
        shape_ptr(new Rectangle(1, 2, 20, 10)),
        shape_ptr(new Circle(1, 2, 10)),
        shape_ptr(new Triangle(1, 1, 5, 1, 3, 3))
    };

    for(shape_ptr* i = std::begin(shapes); i != std::end(shapes); ++i) {
        (*i)->write_to(std::cout);
    }
}

g++ コマンドなどでコンパイルすると実行ファイルが生成されます。 実行すると Ruby で書いたプログラムと同じ結果を出力します。

C++ でオブジェクトをデシリアライズする、その1

Ruby で書いたときと同じように、ハードコードするところから始めてみます。

#include <fstream>
#include <iostream>
#include <memory>
#include <vector>
#include "shape.hpp"

typedef std::shared_ptr<Shape> shape_ptr;
typedef std::vector<shape_ptr> Shapes;

int main(int, char**) {
    Shapes shapes;

    std::ifstream ifs("shapes.dat");

    for (;;) {
        std::string name;
        ifs >> name;
        if (ifs.eof()) {
            break;
        }

        if (name == "Rectangle") {
            shapes.push_back(shape_ptr(new Rectangle(ifs)));
        } else if (name == "Circle") {
            shapes.push_back(shape_ptr(new Circle(ifs)));
        } else if (name == "Triangle") {
            shapes.push_back(shape_ptr(new Triangle(ifs)));
        }
    }

    for (Shapes::const_iterator i = shapes.begin(); i != shapes.end(); ++i) {
        (*i)->write_to(std::cout);
    }
}

図形クラスにも IO からデータを読み込めるようにします。

コードが長くなるので、追加分だけ示します。

// 略
class Rectangle : public Shape {
public:
    // 略
    Rectangle(std::istream& in) {
        in >> x >> y >> width >> height;
    }
    // 略
};

class Circle : public Shape {
public:
    // 略
    Circle(std::istream& in) {
        in >> x >> y >> r;
    }
    // 略
};

class Triangle : public Shape {
public:
    // 略
    Triangle(std::istream& in) {
        in >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
    }
    // 略
};
// 略

ところで。 データを IO に出力する挿入演算子 ( << ) や IO からデータを入力する抽出演算子 (>>) は、シフト演算子をオーバーロードしたもので、C++ プログラミングで最初に遭遇する C++ の奇妙なところだと思います。 なかなか慣れないですし、人によってはずっと慣れることのない代物かもしれませんが、使い所を選べばデータを流れとしてやりとりできるのでとても重宝します。

閑話休題。

C++ でオブジェクトをデシリアライズする、その2

C++ の構文でハードコードせずに、文字列に対応するクラスのインスタンスを生成するにはどうしたらよいでしょう。

C++ には Ruby のように文字列からクラスを見つける仕組みは用意されていません。 自分で書く必要があります。

ここでは Deserializer というクラスと、文字列とデシリアライザの対応付けを事前に格納した deserializers を用意します*1

#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <vector>
#include "shape.hpp"

typedef std::shared_ptr<Shape> shape_ptr;
typedef std::vector<shape_ptr> Shapes;

class Deserializer {
public:
    virtual shape_ptr create(std::istream&) const = 0;
};

template<class T> class DeserializerImpl : public Deserializer {
    shape_ptr create(std::istream& in) const {
        return shape_ptr(new T(in));
    }
};

const std::map<std::string, std::shared_ptr<const Deserializer> > deserializers = {
    {"Rectangle", std::shared_ptr<Deserializer>(new DeserializerImpl<Rectangle>)},
    {"Circle", std::shared_ptr<Deserializer>(new DeserializerImpl<Circle>)},
    {"Triangle", std::shared_ptr<Deserializer>(new DeserializerImpl<Triangle>)}
};

int main(int, char**) {
    Shapes shapes;

    std::cout << "Deserializer 3" << std::endl;
    std::ifstream ifs("shapes.dat");
    for (;;) {
        std::string name;
        ifs >> name;
        if (ifs.eof()) {
            break;
        }

        shapes.push_back(deserializers.at(name)->create(ifs));
    }

    for (Shapes::const_iterator i = shapes.begin(); i != shapes.end(); ++i) {
        (*i)->write_to(std::cout);
    }
}

C++ ではクラスの世界とインスタンスの世界は別世界であるため、実行時に手に入るデータから new 演算子を使ってインスタンスを生成することはできません。

そのためインスタンスを生成する操作をインスタンスの世界に持ち込む仕組みが必要になります。

まず、クラステンプレートでインスタンスを生成するメソッドを持つクラスを定義します。

これによって例えば次のようなクラスが定義されます。

// テンプレートによって生成されるクラスの定義を便宜的に書き下したもの
class DeserializerImplRectangle : public Deserializer {
    shape_ptr create(std::istream& in) const {
        return shape_ptr(new Rectangle(in));
    }
};

このクラスをインスタンス化することで Rectangle の生成操作を値として扱えるようになります。

Deserializer* deserializer = new DeserializerImplRectangle;
deserializer->create(ifs);

Rectangle, Circle, Triangle のそれぞれの生成操作をオブジェクトにして、辞書 ( std::map ) に文字列とオブジェクトの対応付けを格納します。

const std::map<std::string, std::shared_ptr<const Deserializer> > deserializers = {
    {"Rectangle", std::shared_ptr<Deserializer>(new DeserializerImpl<Rectangle>)},
    {"Circle", std::shared_ptr<Deserializer>(new DeserializerImpl<Circle>)},
    {"Triangle", std::shared_ptr<Deserializer>(new DeserializerImpl<Triangle>)}
};

これでようやく文字列からインスタンスの生成操作を取得することができるようになり、取得した生成操作を使ってインスタンスを生成することができるようになりました。

Ruby では、実行環境がこのような辞書を持っていて、プログラムからその辞書を実行時に利用でき、クラスもオブジェクトであるため辞書から値としてクラスを取り出すことができ、そのクラスのメソッド .new を当たり前に利用できるようになっています。

逆にこの C++ のコードは、Ruby のそのような挙動を再現しようとしたものと言えるかもしれません。

まとめ

  • シリアライズは、オブジェクト自身が自分が何者なのかを知っているので、データの形式と内容が決まればそれほど難しくはありません。
  • デシリアライズは、入力した内容が何者なのかを調べなければならず、それを誰かに問い合わせなければなりません。何者かがわかってもそれを復元する仕組みが用意されていなければなりません。
  • インスタンスの生成は、プログラミング言語によってはプログラムの実行環境とは別の階層にあり、それを超えるための仕組みを実現することが強いられます。メタプログラミングの入り口です。
  • ネタプログラミングにしては、今回はネタのひねりが今ひとつという自己評価。
  • 事業部では「メタプログラミング Ruby 読書会」も開催しています。 気になる方はこちらからお問い合わせを。

agile.esm.co.jp

*1:Mac の g++ でコンパイルすると "cannot be initialized with an initializer list" のようなエラーが出るかもしれません。その場合は -std=gnu++11 オプションをつけてコンパイルしてみてください。

RubyKaigi 2025 に Drinkup Sponsor として協賛します🍊🍻

こんにちは!maimuです。

本日は RubyKaigi 2025 へのスポンサー協賛のお知らせです🍻

永和システムマネジメントは RubyKaigi 2025 へ Drinkup Sponsor として協賛します。

募集開始はまだ少し先になりますが、本ブログの内容をぜひチェックいただき、イベントページ公開までお待ちください。

Drinkup Sponsor

RubyKaigi 2025 は愛媛県松山市で開催されます。

RubyKaigi 2025 のロゴから真っ先にみかんが連想されますが、松山といえば鯛めしも有名ですね。

今回は、鯛めしをはじめとした美味しい料理と日本酒を提供するドリンクアップを会期最終日である4月18日(金)の夜に開催します。

会場やお申し込みについての詳細は追ってご案内いたしますため、永和システムマネジメントのXアカウントをフォローして続報をお待ちください!

https://x.com/rubyagile

また、昨年と同様に今回も "First-Timer 枠" として RubyKaigi に初参加の方がお申し込みいただける枠を用意する予定です。 RubyKaigiに初めて参加される方でドリンクアップへの参加を迷われている方はぜひこちらの枠をご活用ください。

料理とお酒を堪能しながら、Rubyist 同士の交流を楽しめるように準備を進めています! RubyKaigi 本編とドリンクアップ会場で皆さんとお会いできることを楽しみにしています😄

本編には @koic と @junk0612 の2名が登壇します!

また、弊社から @koic@junk0612 の2名がスピーカーとして登壇します。 こちらも楽しみですね。

blog.agile.esm.co.jp

RubyKaigi 2025 の開催まで早いもので残り約1ヶ月です。 当日に向けて気持ちを高めて、みんなで RubyKaigi を満喫しましょう!

ドリンクアップの続報についても、ぜひお楽しみに🍻


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

agile.esm.co.jp

RubyKaigi 2025 に永和システムマネジメントから @koic @junk0612 の2人が登壇します

2025年4月16日(水) から18日(金) の3日間にわたって開催される RubyKaigi 2025 に永和システムマネジメントから @koic (Day 2) 、 @junk0612 (Day 2) の2人が登壇します。

rubykaigi.org

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

4月17日(木) 14:40-15:10 @koic 『RuboCop: Modularity and AST Insights』

@koic です。今年は『RuboCop: Modularity and AST Insights』というタイトルで話します。

rubykaigi.org

キーワードは3つ「プラグイン、アドオン、AST」です。

プラグインとは最近 RuboCop に導入したプラグインシステムです。bundle update rubocop を行った際に遭遇した開発者もいるのではと思いますが、その背景なども踏まえて話します。プラグインには利用者と開発者のそれぞれ向けのマイグレーションパスがあり、その裏側について知る機会になると思います。rubocop-xxx (例えば rubocop-performance, rubocop-rails, rubocop-rspec) といった感じの自作を含めた RuboCop 拡張の利用者ならびに開発者の方は、ぜひ聞いてもらえると「そういったことか。」がわかるようになると思います。

アドオンは Ruby LSP Add-on という Ruby LSP への RuboCop 組み込みに関する話です。こちらは既存の Ruby LSP に対して機能が十分でないため、まだ直接的なユーザー影響はないと思うのですが、今後 Ruby LSP のバックエンド RuboCop をどのような位置付けにしたいのか、またその過程でのユーザー影響もあわせてお話しすることになりそうです。

最後に AST ですが、これは今後の RuboCop のバックエンドパーサーに関する話になります。昨年の RubyKaigi 2024 のトークで伝えたとおり、現在の RuboCop はバックエンドパーサーとして、Parser gem と Prism (正確には Prism::Translation::Parser) を選択できるようにしていますが、それを踏まえてバックエンドパーサーの現状と近未来のヴィジョンを語ります。また、RuboCop にとってベターな AST とは何か?といった課題についても述べますので、その辺りは RubyKaigi で議論したいテーマの呼び水となるかもしれません。こちらのバックエンドパーサーについても、近未来でユーザー影響がある話になると思いますので、ぜひ聞いてもらいたいトピックです。

そんな感じで、今年は RuboCop ユーザーにいくらかの影響が起きるトークを引っ提げての登壇です。今年もこれを30分で話すの?誰が?という盛り盛りな感じになりそうですが、様式美なので仕方ないですね。

昨年話した『RuboCop: LSP and Prism』の続編みたいな側面もありますので、昨年のトークは LSP や Prism について事前知識の予習になると思います。よければご参照ください。

rubykaigi.org

もちろん独立したトークとして楽しめるようにしますので、お楽しみに。

4月17日(木) 16:20-16:50 @junk0612 『The Implementations of Advanced LR Parser Algorithm』

@junk0612 です。今年は『The Implementations of Advanced LR Parser Algorithm』というタイトルで発表します。

rubykaigi.org

発表のテーマをひとことで言うなら「IELR とはなにか?」になりそうです。

この1年、Lrama に IELR という "Advanced LR Parser Algorithm" を実装してきましたが、その道のりはひたすらに論文との格闘でした。実装しては論文と向き合って少しずつ理解を深め、それをまた実装に反映し……という地道な進み方でしたが、一年という長い期間じっくり向き合ったことで多くの気づきを得ました。それらをまとめ、理論面と実践面の2つに大きく分けてお話しします。

  • デファクトスタンダードである LALR にはどんな問題があるのか
  • その問題を IELR ではどうやって解決しようとしているのか
  • IELR と既存の手法にはどのような違いがあるのか
  • Lrama において IELR はどのように実装されたのか
  • IELR を適用すると Lrama-gen parser はどのように変わるのか

などが主なトピックになる予定です。

昨年の発表を話したことをある程度前提に置かないとおそらく発表時間内におさまらないので、可能であれば予習をしておいていただけるとより楽しめる内容になると思います。

rubykaigi.org

ちなみに、IELR に関する理論・実装の発表は Ruby に限らず稀有であり、またある程度複雑な文法構造を持ち、かつ広く使われている (つまりRuby のような) 言語に対して適用してパーサーを生成する例というのも調べる限りでは出てきません。コンピュータサイエンス的に見ても意義のある発表になると思いますので、お時間がある方はぜひお越しください。


それでは本編をお楽しみに。愛媛県松山市の会場でお会いしましょう。

RubyKaigi 2025 に Drinkup スポンサーとしても参加している永和システムマネジメントでは、Ruby とアジャイルソフトウェア開発や構文解析器の研究を通じてコミュニティと成長したいエンジニアを絶賛募集しています。

agile.esm.co.jp

Rails / OSS パッチ会 2025年3月 (オンライン開催) のお知らせ

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

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

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

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

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

discord.gg

来月開催の RubyKaigi 2025 に関する話題などあると思います。

rubykaigi.org

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


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

agile.esm.co.jp

TokyoWomen.rb #1 に maimu が登壇します!

2025年3月1日に開催される TokyoWomen.rb #1 にアジャイル事業部から @maimuが登壇します。

tokyowomenrb.connpass.com

maimu 『Rails 1.0 のコードで学ぶ find_by_* と method_missing の仕組み』

最近、ドーナツ屋さんの開拓にハマっている maimu です。

TokyoWomen.rb #1 で「Rails 1.0 のコードで学ぶ find_by_* と method_missing の仕組み」というタイトルで発表をします。

TokyoWomen.rb #1 のテーマは「Rubyっておもしろい!」です。

私が Ruby のおもしろさを実感したタイミングはたくさんあるのですが、 Ruby のメタプログラミングを初めて勉強した時に今まで知らなかった世界が広がっていくおもしろさがありました。 その流れで Rails 1.0 のコードリーディングをした際に特におもしろいと感じた find_by_*method_missing に焦点を当てて、当時の背景や実装内容を私がおもしろいと感じたポイントともに解説していきます。

TokyoWomen.rb #1 は開催日当日まで参加登録が可能です。 発表内容も多岐に渡るため、ご都合が合う方はぜひ現地でお会いできると嬉しいです!

tokyowomenrb.connpass.com


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

agile.esm.co.jp