Classi開発者ブログ

教育プラットフォーム「Classi」を開発・運営するチームの開発者ブログです。

視覚障害者の声から始まったtetoruのアクセシビリティ改善の取り組み

保護者連絡サービス「tetoru」のプロダクトマネージャーを担当している米谷です。

tetoruは全国5,000以上の教育機関で、200万人を超える保護者の方にご利用いただいています。今回は、ある保護者の方のSNS投稿をきっかけとして取り組んだ、tetoruアプリのアクセシビリティ改善についてお伝えします。

視覚障害のある保護者の声

ある日、視覚障害のある保護者のSNSの投稿が目に留まりました。そこでは、お子さんの通う学校で利用されている連絡アプリの音声読み上げについてやりとりされており、その対応状況によっては視覚障害のある方にとって利用そのものが困難になるケースがあることを知りました。

この投稿を受け、tetoruの保護者向けアプリが、視覚障害のある方にとって不自由なく使えるものになっているかを確認したいと思い、私自身でも音声読み上げ機能を試してみることにしました。

実際にiOSのVoiceOverで操作してみると、テキスト部分については大きな課題はなかったものの、アイコンや画像が使われている箇所で一部が適切に読み上げられていないことに気づきました。

エンジニアへの連携と対応

チームにSNSの投稿内容と検証結果を共有したところ、メンバーが早速実装状況を調査し、いくつかの課題と改修方針を提案してくれました。主な課題は以下です。

  • アイコンの読み上げが不十分
  • ブックマークの操作や状態が不明瞭
  • 未読・既読といった状態変更の対応不足
  • 検索UIの読み上げが不十分

今回の改修では、アプリのトップページでもある学校からの連絡一覧画面のアクセシビリティ対応を重点的に行いました。この画面は学校からの緊急連絡などを確認するために利用されるため、優先的に改善することにしました。

iOSのVoiceOver対応では、要素の役割(accessibilityLabel)や操作のヒント(accessibilityHint)、状態変化への対応(UIAccessibility.post)などの適切な設定を行いました。また、AndroidのTalkBackにおいても、読み上げ範囲をアイコンなどの要素ごとに細かく分割して説明(contentDescription)を設定したり、iOSと同様に状態変化を動的に読み上げる対応を行いました。

さらなる改善としての文字サイズの可変対応

音声読み上げ機能の改善を進める中で、以前から一部のユーザーの方よりご意見をいただいていた「文字サイズが小さい」という課題についても、まずは学校からの連絡一覧と詳細画面について対応しました。

Androidは標準で文字サイズの変更に対応していましたが、iOSでは文字サイズが固定値で実装されていたので、OSの設定に合わせて文字サイズが可変となるよう調整を行いました。

この改善では、デザイナーがiOSのDynamic Typeの挙動を理解するために、SwiftUIを学習して実際にどのように文字サイズが変わるのかといった技術的な理解を深めながら、既存のUIに大きく影響が出ないように文字サイズの定義を提案してくれました。

おわりに

2024年4月から改正障害者差別解消法が施行され、事業者による「障害のある人への合理的配慮の提供」が義務化されました。

今回の対応はウェブアクセシビリティの規格である『JIS X 8341-3:2016』の準拠を意図するものではありませんが、多くのユーザーに日々活用していただく中で、少しでも早く改善することを優先しました。

また、多様な保護者の方への対応という観点では、日本語を母語としない方々にもtetoruを快適にお使いいただけるよう、学校からの連絡を自動翻訳する機能のリリースを2025年9月に予定しています。視覚障害のある方への配慮と同様に、言語の違いも学校と保護者のコミュニケーションにおける大きな障壁となる場合があります。

tetoruは今後もより多くの利用者にとって使いやすいサービスを目指し、引き続きアクセシビリティの向上に取り組んでいきます。

Classiのエンジニアが 関西Ruby会議08 に参加しました

はじめに

2025年6月に入社しました、id:tommy1038 です!

2025年6月28日、京都・先斗町歌舞練場にて開催された「関西Ruby会議08」に参加してきました。

regional.rubykaigi.org

関西圏ではこれまでも「大阪Ruby会議」など地域のRubyイベントが継続的に開催されてきましたが、「関西Ruby会議」としての開催は実に8年ぶり。 久しぶりにこの“冠”が復活したこともあり、全国から多くのRubyistが集まりました。

会場となった先斗町歌舞練場は、歴史ある建物で、出囃子や「めくり」などの演出もあり、Rubyのイベントでありながら、どこか和の趣が感じられる特別な空間でした。

関西Ruby会議08の会場(先斗町歌舞練場)

会場内にはスポンサー企業のブースや書籍紹介スペースも設けられ、交流の場としても大いに賑わっていました。 Rubyという言語を通じて、これほど多様な表現や熱量が集まる場があるのだと、改めて実感しました。

気になったKeynoteやSessionをいくつかピックアップしてご紹介します。

Witchcraft for Memory by Masataka Kuwabara(@pocke)さん

Ruby/RBSコミッターでもある @pocke さんによるKeynoteです。
RBS/Steepまわりのメモリ削減に関する工夫が詰まっており、とても学びの多い発表でした。

前半は、Rubyの memory_profiler では把握しづらいピーク時のメモリ使用状況にアプローチするためのツール「Majo」の紹介。

github.com

Cレベルの TracePoint APIを活用して、

  • オブジェクト生成・解放のフック
  • GCを生き残ったオブジェクトのみを記録
  • 記録は Ruby オブジェクトを使わず、Cの構造体と配列で実施

といった低レイヤーなアプローチが印象的でした。
「GCが走っているときに、GCを走らせてはいけない」── そんな制約のなかで、工夫を凝らして適切に処理する発想と技術力には、心から感動しました。

後半では、SteepのLSPサーバーにおけるworkerプロセスのメモリ増加問題に対し、「Refork」という手法で解決を図った取り組みが紹介されました。

Steepでの refork 実装では、まず管理プロセスが全ワーカープロセスをforkし、一度型検査を行ってメモリを“暖気”。
その後、各ワーカープロセスがさらに新しいワーカーをforkし、古いプロセスを順次終了させていく流れになっていました。
この過程での課題や、実運用に耐える仕組みに仕上げていくまでの苦労と工夫が丁寧に語られ、非常に勉強になりました。

普段の業務では、Rubyのメモリ管理やGCについて意識する機会は少ないですが、こうした低レイヤーの知見に触れることで、Rubyの内部動作やパフォーマンス改善の可能性を強く感じることができました。

Masataka Kuwabara さん、素晴らしい発表をありがとうございました。

資料も公開されていますので、詳細を知りたい方はこちらもぜひご覧ください。

speakerdeck.com

「1ヶ月でWebサービスを作る会」で出会った rails new、そして今に至る rails new by kiryuanzu さん

社内でもおなじみ、id:kiryuanzu さんによるセッション。

自身が開発・ローンチしたポッドキャスト系Webサービスを題材に、開発の過程で直面した壁や、それをどう乗り越えたかをリアルに語ってくれました。

「どうすれば本当にリリースまでたどり着けるのか?」
この問いに向き合いながら、“やるぞ!!” と思えるエネルギーを参加者に届けてくれる力強い発表でした。

特に印象的だったのは、ローンチ達成のための3つの秘訣です。

まず1つ目は、「小さく作って出す」こと。
ポッドキャストのRSSフィード発行という最小限の目標に絞り、3週間という短期間で運用開始まで持ち込んだスピード感には、自分も大いに刺激を受けました。

次に、「様子を実況する」こと。
プロポーザル提出時点でサービスが半分もできていなかったという裏話には驚かされましたが、SNSで制作の過程を発信し、自らを奮い立たせるスタイルがとても印象的でした。

そして3つ目は、「自分が最初のユーザーであること」。
本当に “あったらいいな” と思えるサービスを作り、自分で使い続けることで、愛着と改善意欲を自然と保ち続けられるという気づきは、個人開発を続ける上での重要なヒントだと感じました。

この3つのシンプルで本質的な行動が、「つくるだけ」で終わらず、ちゃんと世の中に届ける力になっている。 個人開発で立ち止まりがちな人こそ、背中を押してもらえる発表だったと思います。

kiryuanzu さん、素晴らしいお話をありがとうございました。

資料も公開されていますので、詳細を知りたい方はこちらもぜひご覧ください。

speakerdeck.com

ちなみに、登壇に至るまでの経緯や準備の様子については、こちらのブログで紹介されています。

tech.classi.jp

ふだんのWEB技術スタックだけでアート作品を作ってみる by Akira Yagi さん

八木章(@akira888)さんによるセッション「ふつうの技術スタックでアート作品を作ってみる」では、Rails・Hotwire・HTML・CSSといったおなじみの技術を用いて制作された、時計モチーフのアート作品が紹介されました。

私自身も、過去に Processing や p5.js を使ってインタラクティブな作品を作った経験があり、共感しながら聴き入ってしまいました。

今回の挑戦が面白いのは、特別なライブラリやフレームワークを使わず、いつものWebアプリ開発の延長線上で表現に挑んでいる点です。

  • HTMLとCSSで時計のビジュアルを構成
  • 針の動きをCSSアニメーションで表現
  • 時刻やパターンのロジックをRailsで生成
  • 時間経過による切り替えをStimulusで制御

という構成で、MVCの概念をそのままアートに応用していました。 時計を構成するモデル設計やマッピングロジックの美しさも印象的で、技術と表現が見事に調和していました。

中でも心に残ったのは、「Railsを使っても、ユーザーアクションのない作品を作っていいんです」というメッセージ。 Rubyとアート、その両方を大切にしている姿勢が伝わってきて、温かい気持ちになるセッションでした。

Akira Yagi さん、素敵な発表をありがとうございました。

資料も公開されていますので、詳細を知りたい方はこちらもぜひご覧ください。

speakerdeck.com

Rubyで世界を作ってみる話 by Akira Matsuda さん

Matsuda さんによるセッション「Rubyで世界を作ってみる話」は、Rubyのオブジェクト指向表現を用いて “世界” をモデリングし直すという、遊び心と技術的探究心に満ちたチャレンジでした。

class Atom から始まり、電子や分子といった構成要素を定義していく中で、Rubyのクラスやモジュールを通じて現実世界を抽象化していく──
まさにオブジェクト指向の原点に立ち返るような体験でした。

中でも印象的だったのが、InChI記法で記述された複雑な化学構造式をRubyでパースする実装です。 構文と意味の“橋渡し”としてのプログラムの美しさがあり、DSL的な発想としても非常に刺激的でした。

さらに、Gitの履歴を使って世界の始まり(ビッグバン)まで遡ろうと試みるも、1970年が技術的な限界だったというオチには、会場から笑いが起こり、セッション全体に心地よいユーモアが漂っていました。

会場が京都だったこともあり、京大の先生方の理論をRubyに取り込もうとする試みも紹介され、参加者の関心を集めていました。

業務アプリの枠を超え、Rubyという言語の表現力を最大限に活かして「世界を再構築する」という視点は、 コードを書く楽しさや、創造する喜びをあらためて思い出させてくれるセッションでした。

Akira Matsuda さん、素晴らしい発表をありがとうございました。

それぞれの「関西Ruby会議08」

一緒に参加したClassiメンバーも、それぞれ自分の言葉で感想を残しています。

雰囲気や熱量の伝わる素敵な記事ばかりなので、よければこちらも覗いてみてください!

kiryuanzuさんの登壇資料より

歌舞練場という普通の技術カンファレンスではやらないような特別感のある会場と演出がとても良く、自分でも何か手を動かしたくなる刺激的なトークばかりで最高に楽しい地域Ruby会議でした!

ブログの詳細はこちら 👉 関西Ruby会議08に参加してきた - kozy4324の日記

私自身、人生初の技術カンファレンスでした。 運営の方はとても熱量をもってやられており、登壇された方々の内容もとてもおもしろく、自分で手を動かしたくてウズウズしてしまいました! また次回も参加したいと思いました!!

ブログの詳細はこちら 👉 関西RubyKaigi08に行ってきた - nekobitsdreams’s diary

今回のRuby会議に参加し、「個人開発をしたい」と素直に思いました。バグとの戦いも含めてそれも「ものづくりの楽しさ」であることを登壇者の方のお話から気付かされました。 これから、楽しみながらいろんなことに挑戦していきたいです。

ブログの詳細はこちら 👉 関西Ruby会議08に参加しました!|Akinko

初めての大型技術系カンファレンスで刺激がたくさんありました!特に個人開発の登壇をしていらっしゃる方が多くて参考になる点が多く、自分も趣味と重ねて個人開発を進めていきたいです!目指せ登壇!

ブログの詳細はこちら 👉 関西RubyKaigi行ってきた件! - butyooo’s blog

初めての登壇でとても緊張しましたが、無事終えることができ本当に良かったです!発表準備から当日までの過程を暖かく見守ってくださったClassiのメンバーの方々に改めて感謝の気持ちを伝えたいです。

ブログの詳細はこちら 👉 関西Ruby会議08に登壇してきた、それらにまつわる全ての感情 - 桐生あんずです

終わりに

関西Ruby会議08。ここで紹介しきれなかったセッションも含めて、本当に刺激の多い一日でした。
低レイヤーの深掘りからアートの表現、個人開発のリアルな奮闘記まで、「Rubyでこんなこともできるんだ」という気づきがいくつもあり、あらためてこの言語の懐の深さを実感しました。

ふだんの業務ではなかなか出会えない視点や発想に触れ、自分も何か作ってみたいな、という気持ちが自然と湧いてきました。 歴史ある先斗町歌舞練場という特別な場所で、Rubyへの愛や技術への熱量が会場のあちこちから伝わってくる、うれしくて、ちょっと誇らしい時間でした。

運営のみなさま、登壇者のみなさま、本当にありがとうございました!

最後に、会場で撮ったClassiメンバーとの写真や、Matzとの記念ショットをいくつか載せておきます📸

ClassiメンバーとMatzとの記念写真など

ライブラリメンテナンスのための自作ESLintルール作成

こんにちは、プラットフォーム部の id:lacolacoです。

Classi社内では、複数のWebアプリケーションで共通のUIコンポーネントを社内ライブラリ化しています。ライブラリを長くメンテナンスしていると、過去に提供していたAPIを廃止して、新しいAPIに置き換えたいことが多々あります。いきなり古いAPIを消して新しいAPIを提供する破壊的変更のアプローチは、社内ライブラリであれば利用者とコミュニケーションしやすいため妥協してしまいそうになります。しかし、破壊的変更への追従が利用者側で負担となって棚上げされた結果、後になって急いで適用して欲しいセキュリティパッチのバージョンアップがなかなか適用できない、なんてことになるのは避けたいところです。

そんな流れで、今回はライブラリメンテナンスの上でAPIの非推奨化から廃止までのプロセスを支援するためのESLintルールを自作した話をします。AI要素もちょっとあります。

社内ライブラリと破壊的変更

Classiで採用しているAngularフレームワークを例にあげると、Angularの非推奨化ポリシーでは廃止予定のAPIはまず非推奨APIとしてマークされ、最低でも2メジャーバージョン(1年間)の猶予期間が与えられます。その猶予期間のあとのメジャーバージョンにて、非推奨APIは破壊的変更として廃止されます。社内ライブラリは広く使われるOSSではないのでここまでの厳格なポリシーは必要ありませんが、少なくとも非推奨化の段階を踏み、既存の利用箇所を新しいAPIに移行したうえで安全に廃止できるようなプロセスを取りたいと考えています。

そういうモチベーションで、社内ライブラリのTypeScriptコードにはいくつもJSDocの @deprecated アノテーションが付けられたAPIがありましたが、いざ廃止しようとすると困ることがありました。まず、現状、どのAPIに非推奨マークが付けられているのかの一覧もなく、毎回コード検索をするしかありません。また、一度にすべての非推奨APIを廃止するわけではなく、残すものもあるため、 @deprecated アノテーションの有無だけでは一律に処理ができません。

やりたいことは以下の2点です:

  • ライブラリ中で非推奨化されているAPIが一覧できる
  • 削除されるべき非推奨APIと、まだ残しておきたい非推奨APIが区別できるようになる

これを実現するにあたって考えたのが、自作ESLintルールでした。

APIの非推奨アノテーションを検出するESLintルール

TypeScript ESLintにはno-deprecatedルールがありますが、これは非推奨マークされたAPIを「参照している」コードを検出するものです。今回欲しいのは、ライブラリ開発者側の立場で、非推奨マークされたAPIの「宣言」を検出するものです。これはある程度探した限りでは見つかりませんでしたので、自作することにしました。

シンプルなルール適用例として、次のような設定をすればライブラリ中のすべての @deprecated アノテーションがついた宣言をエラーとして検出します。

// eslint.config.js  
import customRules from './tools/eslint-rules';

export default [  
  {  
    plugins: {  
      custom: customRules,  
    },  
    rules: {  
      'custom/deprecated': 'error',   
    },  
  },  
];  

これだけだと残しておきたい非推奨APIを検出してしまうので、つぎのように allow オプションによって明示的に許可された名前のシンボルは対象外とできるようにしました。

// eslint.config.js  
export default [  
  {  
    rules: {  
      'custom/deprecated': [  
        'error',  
        {  
          allow: ['allowedFunction', 'AllowedClass'], // 許可する名前のリスト  
        },  
      ],  
    },  
  },  
];  

クラスの一部のメソッドだけ非推奨化することもあるため、 ClassName.memberName というパターンもサポートしています。

{  
  allow: [  
    'MyClass.deprecatedMethod',   
    'MyClass.deprecatedProp',  
  ];  
}  

このようなルールを作成してESLintを実行すると、既存の非推奨APIがエラーとして可視化されます。最初は仕方ないのでひとつひとつ手で allow 配列に入れていくと、 allow 配列はまさに「ライブラリ中で非推奨化されているAPIが一覧できる」場所になりました。

この状態ができてしまえばあとは簡単です。廃止したいAPIだけを allow 配列から取り除き、ESLintを実行すると対応すべきコードがわかります。直近のアップデートではそこそこの数の非推奨APIを削除したのですが、 allow 配列をいじったあとのコード変更作業はAI(今回はGitHub Copilot ChatのAgentモード)だけで完結しました。

プロンプト:

TDDを開始

- 目的: 非推奨マークされたAPIのうち、eslint.config.ts で許可されていないものだけを廃止する  
- テストコマンド: pnpm lint  
- 完了条件: ESLintエラーから custom/deprecated ルールのエラーがなくなる  
- 禁止事項  
  - ESLintエラーと直接関係のないコードの変更

完了条件が明確で、ESLintのエラー出力からどのファイルのどの宣言が処理対象か迷うこともないので、残っていた非推奨APIへの参照を置き換えつつAPIの削除までスムーズに進行しました。「TDDを開始」と言ってテストの仕方と完了条件を教えておけばだいたいうまくいく。

ESLintルールの実装

今回のESLintルールは TypeScript ESLintの力を借りて、TypeScriptの型情報を使っています。2025年5月に開催されたTSKaigi 2025でも自作ESLintルールの話は多く、それに触発された部分もけっこうあります。

基本的にはそれぞれの宣言についてJSDocが付いているか、付いていれば @deprecated アノテーションが含まれているか、ということを見ていくだけなのですが、一部の構文ではちょっとした工夫が必要だったので書いておきます。とはいえ、実際には自分はテストコードだけを書いていて、ASTを走査する実装コードはほとんどGitHub Copilot Chatに書かせています。

変数宣言のJSDoc

TypeScriptの変数宣言に付いたJSDocは、それぞれの変数の宣言(VariableDeclarator)ではなく const といったレベル(VariableDeclaration)に付きます。これは const a = 1, b = 2 のような構文がありえるためですね。この場合、JSDocが付いているノードと、報告すべきシンボルの名前を取り出すノードがずれるので注意が必要でした。

   /**
     * 変数宣言の@deprecatedチェック
     * JSDocコメントは親のVariableDeclarationに付くため、そちらをチェックする
     */
    const checkVariableDeclaration = (node: TSESTree.VariableDeclarator): void => {
      const name = getIdentifierName(node.id);
      if (!name || isAllowed(name)) {
        return;
      }

      // JSDocコメントは親のVariableDeclarationノードに付いているのでそちらをチェック
      const parentNode = node.parent;
      if (parentNode && parentNode.type === TSESTree.AST_NODE_TYPES.VariableDeclaration) {
        if (hasDeprecatedTag(parentNode)) {
          reportDeprecatedError(node, name);
        }
      }
    };

エクスポート文のJSDoc

エクスポート宣言では、宣言自体とエクスポート文の両方のコメントをチェックします。以下の2つの例は結果的には同じ意味ですが、fooFunction が非推奨APIであるということを検出するには ExportSpecifierFunctionDeclaration の両方を見る必要があります。

/**
 * @deprecated エクスポート文のコメント
 */
export function fooFunction() {}

// または

/**
 * @deprecated 関数自体のコメント
 */
function fooFunction() {}
export { fooFunction };

加えて、APIの命名だけが変更されたケースでは、次のようにエクスポート文でのエイリアスに対する非推奨化もあります。次のようなケースでは ExportSpecifier のノードのJSDocをチェックしつつ、報告するシンボルは ExportSpecifier.name ではなく ExportSpecifier.exported というズレを考慮する必要があります。

export {
   NewExport,
   /**
     * @deprecated Use NewExport instead
     */
   NewExport as DeprecatedExport,
};

まとめ

破壊的変更を安全にリリースしていくための非推奨化プロセスにおいて、当初のねらい通り「ライブラリ中で非推奨化されているAPIが一覧できる」ことと「削除されるべき非推奨APIと、まだ残しておきたい非推奨APIが区別できるようになる」が実現できました。これまではメンテナの脳内にしかなかったライブラリ全体の非推奨化の状況がコードベースに可視化されたことで、忘れても大丈夫になりマインドシェアの解放にも繋がっています。

ESLintに限らず、ASTと仲良くなればソースコードに対する問題解決の幅が大きく広がるので、まだ自作Lintルール未経験の方もぜひ挑戦してみてください。最後に参考リンクを紹介して終わります。

関西Ruby会議08に「『1ヶ月でWebサービスを作る会』で出会った rails new、 そして今に至る rails new」というタイトルで登壇します

こんにちは、Classi でソフトウェアエンジニアをやっている id:kiryuanzu です。

2025年6月28日(土) に京都府京都市の先斗町歌舞練場にて開催される関西Ruby会議08で「『1ヶ月でWebサービスを作る会』で出会った rails new、そして今に至る rails new」というタイトルで登壇させていただくことになりました。

regional.rubykaigi.org

今回はこの発表のプロポーザルを提出した時の背景や、登壇の意気込みについて事前にお伝えしたいと思います。

プロポーザルを提出した際の背景

実は、LT形式ではない少し長めの発表(今回は20分)のプロポーザルを提出したのはこの関西Ruby会議08が初めてでした。
プロポーザルを出すことを本格的に意識した際、まずは関西Ruby会議08の運営の方が書かれた「関西Ruby会議の再開に寄せて」という記事を熟読し、運営の方がどのようなトークを求めているかを自分なりに考えてみました。

note.com

かなり抽象的なテーマですが、Rubyのコードが1行でも発表に含まれているのであれば問題ありません。むしろその人にしか話せない作ったものの「好き」や「苦労」や「思考」などのストーリーを聞きたいと思っています。

「その人にしか話せない作ったものの『好き』や『苦労』」というキーワードを目にした時、自分にとってのそれは学生時代から趣味としていた個人でのWebサービス開発がまず浮かびました。

その上で「聞く人も何か作ろうと思えるような話」も意識しつつ、趣味のPodcastの音声データを自前で配信する個人Webサービスを開発した際の体験談をテーマにプロポーザルを提出するに至りました。
発表の概要は以下のリンクを参照ください。 https://regional.rubykaigi.org/kansai08/presentations/kiryuanzu

発表の意気込み

発表内容は個人開発の体験談がメインとなります。その上で「どうしたら自分の個人サービスをローンチまでやりきれるのか」についても深掘りをする予定です。
この発表を通して、サービスを作っていてローンチを目指している方や、直近の自分のように久々に個人開発したいけれど作る勢いがまだつかない方が「自分もやってみよう」と思えるようなお話ができたらと思います。

先日アップされたタイムテーブル解説記事でも自分が伝えたい発表のイメージを共有してくださっています。こちらも参考にしていただけると幸いです。

関西Ruby会議08 チーフオーガナイザーの ydah さんにタイムテーブルを解説してもらいました - ANDPAD Tech Blog

tech.andpad.co.jp

ydah: そうなんですよね。 まさに「どうしたら個人サービスをローンチまでやりきれるか」についての話を自らの経験をもとに話していただけると思っていて、それは本当に貴重な体験談ですし、個人開発で悩んでる人にとっても、すごく勇気づけられる内容になりそうだなと思っています。 「rails newはするけどローンチまでいかない」って、とても共感する人多いと思うんですよね。これから個人開発を始めたい方にとって非常に参考になるトークだと思います。

筆者以外のトークもたいへん丁寧に解説されています。現地に参加される方は必見の記事です!

おわりに

当日は大変ありがたいことに Classi のメンバーが現地で応援しにきてくださるとのことです!

id:kiryuanzu含む一部のメンバーは Day0 の晩餐会当日の Official Party にも参加予定です。現地でぜひたくさん交流しましょう!

それでは、当日みなさんにお会いできることを楽しみにしております!!

Classiエンジニアの「OSSやっていきの集い」 〜4ヶ月間の取り組みと、初めてのOSSコントリビューション〜

こんにちは。Classiでソフトウェアエンジニアをしている中村( id:kozy4324 )です。

今回は、社内で継続している技術活動「OSSやっていきの集い」についてご紹介します。活動開始から4ヶ月の間に取り組んできたこと、そして実際にOSSプロジェクトへプルリクエストを送ってマージされた経験についてまとめました。

OSSやっていきの集いとは

この活動は、SmartHRさんの取り組み「OSSやっていきの集い」から着想を得て、名称もそのままお借りして始めました。

OSSに関心はあるものの、実際に関わるのはハードルが高く感じられることがあります。私自身もそうでした。 一人では難しく感じることでも、仲間と取り組めば少しずつ前に進めるのではないか。そんな思いからスタートした活動です。

社内でこの活動を始める際には参加するメリットを明確にすることも意識しました。 活動を通じて期待できるアウトカムは以下のようなものです。

組織にとってのメリット

  • OSSに貢献するエンジニアが増え、企業としての発信力も高まる
  • 技術広報の題材として活用できる
  • 開発スキルの向上が期待できる
  • チームを越えた交流が生まれる

個人にとってのメリット

  • OSSに関わる心理的ハードルを下げられる
  • 実践を通じた学びが得られる
  • 社外発信や登壇の機会にもつながる

また、東京Ruby会議12前夜祭での発表 「Rubyと暮らし、OSSに貢献し、登壇する ── 半年間続けた『OSSやっていきの集い』の成果と学び」 にも背中を押されました。実践例を知ることで自分たちの活動がどう発展しうるか、イメージを持てるようになりました。

立ち上げから4ヶ月で取り組んだこと

活動の最初のテーマとして、Rubyのコード整形・静的解析ツールであるRuboCopを選びました。 まずは「RuboCopを知る・使う」ことからスタートし、段階的に理解を深めていきました。

RuboCopの活用に向けた取り組み

  • 基礎固め
    2月4週目〜3月1週目(約2週間)
    RuboCopのGitHubリポジトリや公式ドキュメントを読み、基本的な使い方を習得しました。

  • Copの実装を読む
    3月2週目〜5月2週目(約2ヶ月)
    Style/RedundantConditionなど具体的なCopのコードを読み解きながら、抽象構文木(AST)の概念を学習しました。

  • カスタムCopの作成
    5月3週目〜6月3週目現在(約1ヶ月経過)
    社内プロジェクトで使えそうなカスタムCopの作成にチャレンジしています。例えば社内ライブラリに対して不適切な使い方を検知するCopなど、アイデアレベルから持ち寄り、それをどう実装できるかを参加者で会話しながら取り組んでいます。

  • リリース情報の追跡と適用
    2月4週目〜6月3週目現在(約4ヶ月経過)
    RuboCopのリリースノートを定期的に確認し、社内プロジェクトでのバージョンアップにも取り組んでいます。 エラーが発生した際は「これは貢献のチャンスかもしれない」と前向きに捉える意識も芽生えはじめました。

RuboCop 1.76.0で気づいたエラーメッセージの違和感

ある日、RuboCopを1.76.0にアップデートしたところ次のような指摘を受けるようになりました。

C: Style/ItBlockParameter: Avoid using numbered parameters for multi-line blocks.
            some_ids = some_ids.map do ...
                       ^^^^^^^^^^^^^^^

実際のコードは以下のようになっていました。

some_ids = some_ids.map do
  do_something(with: it)
end

調査したところ、Style/ItBlockParameterEnforcedStyleのデフォルト値がv1.76.0で変更されたことが原因でした。

https://github.com/rubocop/rubocop/releases/tag/v1.76.0

  • #14066: Add EnforcedStyle: allow_single_line as the default to Style/ItBlockParameter. (@koic)

v1.75.xまではonly_numbered_parametersがデフォルトでしたが、v1.76.0からはallow_single_lineが新たに追加され、こちらがデフォルトとなっています。その結果、設定を明示していないプロジェクトでは複数行ブロック内でのitの使用が許容されなくなりました。

このようにエラーの理由は理解できたのですが、表示されるメッセージには少し違和感がありました。

Avoid using numbered parameters for multi-line blocks.

今回のコードでは「numbered parameter(_1, _2など)」は使っておらず、itを使っているにもかかわらずその利用を避けるようにというメッセージに読めてしまいます。

コードとエラーメッセージを見比べても、なぜ警告されているのかが直感的に理解しづらい状況でした。

RuboCopへの修正プルリクエストとマージ

このメッセージの違和感を解消するためエラー文言の修正に特化したプルリクエストを作成しました。

そしてありがたいことに当日中にマージしていただくことができました。これは「OSSやっていきの集い」を始めた当初から目指していた「実際にOSSに貢献できる経験を得る」という目標の達成でもあります。

日々の開発のなかでOSSを継続的に利用していたからこそ、違和感に気づき、改善のきっかけを掴むことができました。 ゼロからのスタートでも数ヶ月で貢献のチャンスを得られたことは非常に嬉しい成果です。

これからの展望

「OSSやっていきの集い」はまだ始まったばかりの取り組みです。今後もRuboCopの内部実装を読み解きながら、カスタムCopの開発や小さな改善の提案を通じて、OSSとの関わりを深めていきたいと考えています。

この活動を通じて、ClassiのエンジニアがOSSと自然に関わり、学びを得て、最終的にはOSSコミュニティに貢献できるような文化を育てていければと思います。

Classi 2025年新卒エンジニア研修「そーだい塾」を開催しました

 こんにちは。Classiのみんなの頼れるお兄さん id:Soudai です。 Classiでは例年、新卒エンジニア向けの研修「そーだい塾」を実施しており、今年も2時間の研修を3回にわたって開催しました。

 今日はこの研修をご紹介しながら、当日の雰囲気やスライドには書いていない部分や大切な考え方をご紹介します。

  1. 第1回:リリースの極意
  2. 第2回:日々の仕事の中で成長する
  3. 第3回:具体と抽象と現場

第1回:リリースの極意

 第1回では、ソフトウェアエンジニアにとって最も重要な「リリース」について取り上げました。

登壇資料

speakerdeck.com

speakerdeck.com

伝えたかった狙い

 まずはエンジニアたるもの、リリースから始まるということでリリースをテーマにしました。 このセッションは例年やっています。

tech.classi.jp

 当日は新卒だけでなく、 id:lacolaco をはじめとしたClassiのエンジニアも参加して、リリースに対する考え方やリリースの重要性の議論も行いました。 2~3年も経てば、データベースの変更が必要な機能のリリースも必要になりますし、数ヶ月もかかるような大きなコードベースのプロジェクト単位のリリースも行うようになります。そういう時にこの話を思い出してほしいのです。そうすれば事前に事故を防ぐことができます。そうやって経験していく中で「これは、そーだいさんが言ってたやつだ」となってほしいなと思っています。

第2回:日々の仕事の中で成長する

 第2回では、エンジニアとしての成長と仕事のコツを紹介しました。 毎日8時間働いていくのですから、その中で成長し、仕事で成果を出し、評価を得ることが重要です。 そのために必要なスキルや考え方を伝えました。

登壇資料

speakerdeck.com

speakerdeck.com

伝えたかった狙い

 この回の資料は、まず知っていることがとても重要な内容を中心に構成しました。 早く知れば知るほど複利が効く内容で、出来なくてもまずは知っておいて出来るようになるまで繰り返すことが大切です。

 意識していればできるようになるスキルですし、逆に言えばこれができない場合はどこかで社会人として躓くことになるでしょう。 だからこそ早めに知識として知っておき、身につけてほしいということで紹介しました。

第3回:具体と抽象と現場

 最終回では、エンジニアにとって重要な思考法である「抽象化と具体化」について深く掘り下げ、それを具体的にどのように実践するかを紹介しました。

登壇資料

speakerdeck.com

speakerdeck.com

伝えたかった狙い

 この話は去年はしておらず、完全な新作です。 抽象化と具体化は、ソフトウェアエンジニアにとって非常に重要なスキルであり、これを身につけることでより良いソフトウェアを作ることができます。 無意識に行っていることも多いですが、意識的に行うことでより効果的に活用でき、再現性が上がります。

 抽象化と具体化の往復を仕事で行っていくうえで、現在の自分の抽象度がどの位置なのか把握することから始めましょう。ということを伝えました。

 そして最後に実際に仕事をするうえで、抽象化と具体化をどのように活用していくかを紹介しました。 顧客が求めているものを理解し、言われたことを作るのではなく、必要なものを作るためにも抽象化と具体化の往復が重要です。

終わりに

 Classiでは2021年から4年間にわたって新卒エンジニア向けの研修「そーだい塾」を実施しています。 もちろん新卒のメンバーがこの研修を受けることによって、すぐに仕事ができるようになるわけではありません。 ですが、2年後、3年後に振り返ったときに「そーだい塾で学んだことが役に立った」と思ってもらえるような内容を提供しているつもりです。

 そして実際に今の2年目、3年目のメンバーからは「改めて今年の新卒研修を眺めていると、そーだい塾で学んだことの解像度が上がっている」と言ってもらえています。 こういう若者の成長を感じられることも、そーだい塾をやっていてよかったなと思う瞬間ですね。

 今年の新卒のメンバーが実際の業務を通じて成長し、数年後に「そーだいさんの言ってたこと、今ならわかる!」と言ってもらえる日が来ることを楽しみにしています。


参考記事

NPS70超。社内AI議事録ツール「Turing」がClassiの"当たり前"になるまで

こんにちは、エンジニアの鳥山です。

Classiでは、2024年の12月ごろから当時最新であったGemini 1.5 Proを用いた議事録生成ツール「Turing」を開発、リリースし、社内のメンバーに使ってもらっています。

tech.classi.jp

本記事では、

  • リリースからおよそ半年経った今、Turingはどの程度普及したのか
  • 利便性や運用性の向上のためにどんな継続的改善をしたのか

の大きく2点に焦点を当てて紹介し、最後にTuringの成功要因についても考察します。

モデルのアップデートや新技術の発表が毎週のように起きる昨今、個人的にはAIをプロダクトに取り入れることのみならず、社内ツールとして使うことにも大きな可能性を感じています。

本記事は単体でもお読み頂けますが、Turingのアーキテクチャなどより詳細な部分にご興味をお持ちの方は、ぜひ前述のブログ記事も併せてお楽しみください。

  • Turingはどの程度普及したのか
  • 利便性や運用性の向上のための工夫
    • Slack任意チャンネルへの投稿
    • インスタンス起動時刻の最適化
  • 成功の要因、そして今後の展望
続きを読む

© 2020 Benesse Corporation. All rights reserved.