PHPerがRubyistになろうとしてつまづいたところ②コンソール

こんにちは!WEBアプリケーションエンジニアの小松です!

この記事は[Enigmo Advent Calendar 2024]の16日目の記事です。  

 

コンソールを使ったデバッグは開発において非常に重要です。フレームワークや言語ごとに特性が異なるため、それぞれの仕組みに慣れる必要があります。以下にPHPRailsを例に、デバッグ手法や注意点を詳しく解説します。


1. PHPデバッグ方法

PHPにはRuby on Railsのような標準的なコンソール機能(例:rails console)が存在しません。そのため、デバッグの際には以下の手法を使うことが一般的です。

  • var_dump()の利用
    PHPでは主にvar_dump()が使われます。これはCLIからの実行でもWEBブラウザ経由のアクセスでも有効です。
    :

    $data = ['name' => 'John', 'age' => 30];
    var_dump($data);
    
  • CLIでのPHPスクリプト実行
    テストスクリプトを作成してCLIから直接実行する方法もあります。これにより、サーバーを介さずにデバッグが可能です。


2. Railsのコンソール機能

Railsには標準でrails consoleが用意されており、デバッグやテストに非常に便利です。ただし、注意すべき点もいくつかあります。

  • 関数のテストが容易
    Railsのコンソールでは、関数やクラスを直接呼び出してテストできます。
    :

    def greet(name)
      "Hello, #{name}!"
    end
    
    puts greet("Alice") #=> Hello, Alice!
    
  • デバッグにおける注意点
    Railsコンソールでのデバッグにはpを使用しますが、PHPvar_dump()と異なるため、切り替えを忘れることがあります。
    :

    data = { name: "John", age: 30 }
    p data #=> {:name=>"John", :age=>30}
    
  • コード変更時の再起動
    コードを変更した場合、Railsコンソールに入り直す必要があります。これを忘れると、古いコードのままデバッグを続けることになり、時間を無駄にする原因になります。


3. RSpecでのデバッグ

RSpecデバッグでもコンソールと似ています。以下に注意点と手法を挙げます。

  • pを利用したデバッグ
    RSpecでは、ログを確認するよりもpを使う方が効率的な場合があります。しかし、つい忘れてしまうことも多いです。
    :

    it "tests addition" do
      result = 2 + 2
      p result #=> 4
      expect(result).to eq(4)
    end
    
  • コード変更時の挙動
    RSpecコードそのものを変更する場合、通常は何もせずにテストを実行できます。しかし、テスト対象のロジックを変更した場合、特定の環境では注意が必要です。

  • コード変更と反映
    テスト用のコード変更は即時反映されますが、今の開発環境では実際のアプリケーションコードを変更した場合はDockerコンテナを再起動する必要がある場合があります。この手順を忘れると、古いコードでデバッグを進めてしまう可能性があります。

    手順:

    1. コードを変更する。
    2. 以下のコマンドでコンテナを再起動する。

結論

PHPRailsRSpec環境それぞれに特有のデバッグ手法と注意点があります。特にRailsやDocker環境ではコード変更時の再起動を忘れがちになります。また、各環境でのデバッグ手法に慣れることで、無駄な時間を減らし、生産性を向上させることができます。

PHPerがRubyistになろうとしてつまづいたところ①シンボル?

こんにちは!WEBアプリケーションエンジニアの小松です!

この記事は[Enigmo Advent Calendar 2024]の15日目の記事です。  

PHPの場合

model['full_name']

こういう変数の持ち方を連想配列と呼んでいただけなので、シンボルキーという言葉と発想がなかったです。

呼び出し方でも

model['full_name'], model[:full_name], model.full_name

などがあり、

<%= debug model %> やログでオブジェクト全体の値が取れてもキーの持ち方が違って取得するのに時間がかかることがありました。

なので、呼び方の具体例や呼び出し方を記載しました。

model['full_name'] のような形式は、文字列キーを持つハッシュから値を取得する方法です。このような形式でのアクセスは、Rubyの基本的なハッシュオブジェクトの操作です。


呼び方の具体例

文字列キーを使ったハッシュアクセス

Rubyでは、ハッシュのキーとして文字列(String)を使う場合に、この形式でアクセスします。

model = { 'full_name' => 'AIR JORDAN 13(エアジョーダン13)' }
puts model['full_name']  # => "AIR JORDAN 13(エアジョーダン13)"

文字列キーアクセスを使う場面

JSONパーサーからのデータ: JSONRubyでパースした場合、デフォルトではハッシュのキーが文字列になります。

シンボルキーを使ったハッシュアクセス

Rubyでは、ハッシュのキーとしてシンボル(Symbol)を使うことも一般的です。この場合は、:full_name のようにしてアクセスします。

model = { full_name: 'AIR JORDAN 13(エアジョーダン13)' }
puts model[:full_name]  # => "AIR JORDAN 13(エアジョーダン13)"

オブジェクト形式(OpenStruct)のアクセス

OpenStruct を使うと、ドット演算子(.)でプロパティにアクセスできます。

require 'ostruct'
model = OpenStruct.new(full_name: 'AIR JORDAN 13(エアジョーダン13)')
puts model.full_name  # => "AIR JORDAN 13(エアジョーダン13)"

 

確認方法

model.class を実行することで、オブジェクトがハッシュなのか、OpenStruct なのか、あるいは別の型なのかを確認できます。その型に応じたアクセス方法を選びましょう。

 

クラス内のインスタンス変数の確認方法

インスタンス変数の取得方法も初めは時間がかかりました。

docs.ruby-lang.org

p obj.instance_variable_get(:@foo) 

このように取得するみたいです。

 

シンボルはRubyのみ存在?

PythonPHP、C、Go、JAVAなどには存在せず、Javascriptには存在するけど、挙動が少し違うようです。

qiita.com

慣れればメリットもあるとの事ですが、他の言語にない概念なので、Ruby使い始めは正直紛らわしかったです。

 

表計算ツールでのサーバ管理台帳を卒業してDCIMツールのNetBoxに移行のことはじめ

こんにちは、インフラグループの片桐です。

この記事はEnigmo Advent Calendar 2024の 14 日目の記事として、サーバ機器管理台帳を表計算ツールから OSSの「NetBox」に移行した取り組みについて紹介します。

はじめに

サーバ機器やネットワーク機器、各機器に付随するIPアドレスの情報など、サーバ機器や関連情報をまとめる為に「機器管理台帳」は欠かせないものになっています。その中で、機器管理台帳はExcelGoogle スプレッドシート等の表計算ツールで管理されているケースもよく見られます。

表計算ツールを台帳として機器管理している場合、台帳の規模が拡大するにつれて、管理すべき各種情報が複数のシートやファイルに分散しがちです。これにより管理コストが増大し、整合性の維持も難しくなります。こうした状況に心当たりのある方も多いのではないでしょうか。

弊部署も同様に、表計算ツールを用いた煩雑な機器管理に悩まされていました。そこで、データセンターのインフラ管理(DCIM)とIPアドレス管理(IPAM)を兼ねるツールであるNetBoxを導入し、機器情報管理の一元化・整合性維持を試みました。本記事では、機器管理台帳の表計算ツール管理からNetBox移行について、取り組み内容、移行に際する知見等を紹介します。

 用語の整理

DCIM

DCIM(Data Center Infrastructure Management)は、データセンターに関連するサーバ機器やネットワーク機器、ラック、配電や配線、設備など、さまざまなリソースを管理・可視化するためのツールや手法のことです。DCIMおよびDCIMツールを導入することで、ハードウェア配置や容量、ネットワーク接続状況などを一元管理することが可能となります。

IPAM

IPAM(IP Address Management)は、ネットワーク内で使用されるIPアドレスを一元的に管理し、その割り当てや利用状況、変更履歴などを可視化・追跡するためのツールや手法のことです。IPAM及びIPAMツールを導入することで、利用可能なアドレス空間のシステム的な管理と、管理に伴ったIP重複割り当ての予防等が可能となります。

NetBox

NetBoxは、DCIMとIPAMの機能を併せ持つOSSです。サーバ機器やラック構成、IPアドレス、ケーブル接続など、データセンターまわりの情報を一元的に、かつわかりやすく管理することに特化しています。 WebインターフェースやREST APIを通して各機器やネットワーク関連のデータを登録・編集・参照できるため、機器情報の管理をするだけでなく、管理の簡略化・自動化も可能です。 お試しで触りたい方向けの公式デモ版サイトも公開されています。 github.com

移行の背景と課題

これまで、弊部署の機器管理台帳には複数ファイル/複数シートを跨ぐGoogle スプレッドシートを使用しており、以下をはじめとする各種情報を管理していました。

  • ハードウェア関連:機材情報、シリアル番号、ラック配置、納品日/保守期限、各機材のLAN接続状況
  • ホスト関連:ホスト名、各NICごとのIPアドレス割り当て状況
  • etc...

台帳上の各機器について、あるシートではホスト名とIPアドレスの紐づけ、あるシートではホスト名とラック上の設置位置の紐づけ...等、1箇所のデータを更新した際に関連するデータを複数シート上で合わせて更新する運用でした。

一方、この管理方式には以下の様な課題もあります。

  • 台帳更新の煩雑さ:
    • 1つの機器について複数ファイル/複数シートを跨いで情報が登録されている場合。
    • シート上のある箇所を変更した際、別シートや別セルの依存箇所も特定して修正する必要がある。
    • 依存箇所を漏れなく特定できる運用フローや仕組み構築が必要になる。
  • 整合性管理の困難さ:
    • 台帳更新の煩雑さ にも関連。
    • 依存箇所の修正漏れが起きやすい状況下にて、依存データ間で整合性の取れていないデータが発生した場合に事実確認の手間が発生する。
  • 外部連携の困難さ:
    • 機器管理台帳に限らず、表計算ツールで作成された各種データファイルが完全なCSV形式で構築されていない場合。
    • 台帳上に存在する情報を読み込んでプログラマブルに利用したい場合や、外部のシステムにデータを取り込む際、各環境が扱える状態に一度変換する手間がある。

これらの課題に対してNetBoxを導入し、対応を試みました。

NetBoxのデプロイ

NetBoxのデプロイ先として、社内向けツール用に構築しているEKS(Amazon Elastic Kubernetes Service)クラスタ上に構築しました。

インストールには、Netbox CommunityのGitHub上で公開されているHelmチャート(netbox-chart)を使用しました。

github.com

helmを利用する場合は利用ガイドを読みながら、ご自分の環境に合わせてvalues.yamlの各値を変更してセットアップする流れとなります。 特に管理者ユーザ周りの設定値はログイン時に使用するため、ご利用の環境に合わせて事前設定することをおすすめします。

NetBoxへのデータ登録

NetBoxに登録できる項目について

データの登録を始める前に、既存の機器管理台帳では何の情報を管理しているのか、NetBoxには何の情報を登録できるのかを一通り把握しておくことを推奨します。

ドキュメントをご参照いただくと分かる通り、NetBoxに登録できる項目は多岐にわたり、かつきめ細かい情報を登録であるため、最初から全ての情報を入れ込むことが難しい場合も想定されます。 (以下NetBox ドキュメントの models 配下の大項目、並びに大項目配下の詳細情報を各機器/各グループ毎に入力可能となっています。)

github.com

もしスモールスタートで「データセンタ内の機器情報、ラックへの機器マウント情報、各機器へのLAN配線、VMホストとゲストVMの紐づけ、各NICへのIPアドレスアサイン」程度で運用を開始したい場合は、以下図のmodel項目を参考に入力していくことで簡素版な環境を構築可能です。

データの登録

NetBoxの導入を検討した当初はスプレッドシート上に散在していた情報を1件ずつ確認しながら手動で登録することも考えていましたが、登録すべき情報を整理していく中で、数百台以上の機器やIPアドレス、接続情報等をすべて手動で移行するのはあまりにも現実的ではない事に気付きました。

一方、NetBoxには機器追加/変更/削除等のデータ操作を楽にする為の仕組みが複数整備されており、一括でのデータ操作が可能となっています。

  • CSV/YAML形式での一括インポート:
    • NetBoxのWEBインターフェースの機能として、CSV/YAML形式でのデータの一括インポートに対応しています。
    • 登録するデータを各形式に整形して事前に整備出来ている場合、各model毎のWEB UI上から楽にデータをインポート可能です。
    • 1行目に各modelに対応するヘッダを、2行目以降に登録するデータを入力する形で定義します。

CSV形式インポートの入力例

  • REST APIでのデータ操作:
    • NetBoxに実装されているREST APIを活用することで、各種データ操作をプログラマブルに行う事も可能です。
    • CSVでのインポートはデータの登録のみ可能ですが、APIを利用することでCRUD各処理を複雑な条件式を絡めて実行することも可能となります。
    • Netbox API Document

上記2種類の一括操作方法を実施して、既存の機器管理台帳上のデータを移行していきました。

スプレッドシートから移行する際の知見

移行前の情報を整理した上で、完全に正規化されたCSVを作成するべき

移行前のスプレッドシートには現状との乖離として、例えば以下の様な不整合が発生していました。

  • 新しいホストに付け替えたIPアドレスが古い機器に付随されたままになっている。
  • ホスト名を変更したが、旧ホスト名のまま台帳に登録されている。

不整合を一つ一つ修正するのは非常に手間の掛かる作業となる上、独自管理の形式から完全な状態のCSV形式に落とし込むことは、手間と時間の掛かる作業となります。

一方、NetBoxには強力なCSVインポート機能が備わっているため、一度完全な状態のCSVを作成してしまえば、NetBoxの運用は直ぐにでも開始可能です。 私は不整合の解消作業は実施したものの、完全な状態のCSVを作成する前に移行を始めてしまった為、変更が必要な所はREST APIを使用して適宜修正する形での対応となりました。

再度移行作業を実施する機会のある際には、完全に正規化されたCSVを作成してから実施すべきと実感しました。

NetBoxに登録する情報の精査と入力先カラムの確認

前述の完全に正規化されたCSVを作成した後は、CSV上のカラムをNetBox上のどのモデルに入れるかを予め検討しておくべきでした。 ラックの情報は dcim > racksに、機器のモデル名やシリアルは dcim > devicesに、IPはipam > ip-addressesに登録出来る、あるいはこの項目について入力できそうな項目が存在しない、等を先行して把握しておくべきでした。

例えば、NetBoxには機器の納品日や保守期限といった項目を入力出来る箇所が標準項目としては存在しません。 そのため、機器情報の自由記述欄となる Comment カラムに入力するか、カスタムフィールドを追加することで、標準機能外の情報管理もNetBox上で可能になります。

一括登録を実施する前に、整理されたCSVの項目とNetBoxの入力項目を比較して、このデータは何処に入るのか?を明確にしておくとスムーズなデータの投入が可能でした。

カスタムフィールドで機材納品日の入力欄を追加する例

NetBox導入によって感じたメリット

情報の一元管理と可視化:

NetBox移行後はIPアドレス、機器モデル、シリアルナンバー、物理配置、接続関係など、あらゆる情報をNetBoxで一元的な管理が可能となりました。 スプレッドシートを利用していた頃は、ある箇所を修正した際依存する情報の修正を、複数シート/複数ファイルに跨って手動で行う必要がありました。 NetBox移行後には依存情報の修正も行われるため、整合性保持にも寄与します。

エクスポート/インポートの柔軟性:

前述の通り、NetBoxにデータを登録する際はCSV/YAML形式でのインポートが可能です。 また、NetBoxに登録されている情報は、CSV/YAML形式でのエクスポートも可能であるため、将来的に別の管理基盤へ移行する際にもデータ移行が容易になることが見込まれます。

拡張性と自動化:

NetBoxにはREST APIや各種WebHookが実装されています。APIによる台帳上のデータの一括操作が可能になった他、WebHookによって台帳に新規機材が追加された際にSlackなどチャットツールに通知する等の対応が可能となりました。別途仕組み作りを実施することで柔軟な対応が可能となるため、今後の拡張性として期待が高まりました。

サーバラックの情報可視化例。ラックの色のついている部分には登録した機器が紐づいている

まとめ

スプレッドシートからNetBoxへと台帳管理を移行した結果、情報一元化や更新作業の効率化が期待できる基盤が整いました。初期構築やデータ整備に手間はかかりましたが、その分、長期的な整合性維持と運用自動化の可能性が大きく広がりました。

一方、現時点では、NetBoxの基本的な機能を用いて、ハードウェアとIPアドレス、簡易な接続情報を一元管理する段階にとどまっています。今後は運用を通じてAPIやWebHookの活用やNetBoxのプラグイン導入など、さらなる効率化と可視化を進めていきたいと考えています。

明日の記事の担当はWEBアプリケーションエンジニアの小松さんです。お楽しみに。


株式会社エニグモ すべての求人一覧

hrmos.co

GoogleスプレッドシートとZapierを用いた勉強会チームのリマインド自動化(Zapier編)

こんにちは!インフラエンジニアの森田です!

この記事はEnigmo Advent Calendar 2024の12日目の記事です。
また、11日目のGoogleスプレッドシート編の続きであるため未読であればそちらからご一読いただければと思います。

前回の記事ではZapierで扱うデータのインプットとなるスプレッドシートの解説を行いましたので、今回は処理とアウトプットを行うZapの解説を行います。

現在以下のZapが稼働していますが、

  • 毎月22日に翌月の発表者へまとめてリマインド
  • 毎週月曜日に発表者へリマインドし、発表予定がなければ募集する
  • 発表があれば開始のアナウンスをし、発表予定がなければスキップのアナウンスをする

今回は翌月の発表者へまとめてリマインドするZapの解説を行いたいと思います。

毎月22日に翌月の発表者へまとめてリマインド

1.毎月22日にトリガー

まず、翌月頭の発表者の準備期間が取れるように毎月22日にトリガーするようにしています。
キャプチャと同じように設定すれば毎月のトリガーとなります。

2.翌月が何月か計算

次の工程で使用するために翌月が何月なのかを取得しています。
具体的には1のトリガーが次に動く日付(翌月の22日)から正規表現で何月かを抽出しています。

import re
print(input_data['next'])
result = re.findall(r'-\d{2}-', input_data['next'])
return {'result' : result[0].replace('-', '')}
3.翌月の行を取得

翌月発表の行をまとめて取得してきています。
具体的には「リマインド管理シート」に開催月という列があったと思いますが、開催月が2で取得したものと同値かつ開催フラグがTRUEの行を取得しています。
注意が必要なのがEventの設定で、「Lookup Spreadsheet Rows」と「Lookup Spreadsheet Rows (Advanced)」という似たイベントが存在しますが、「Lookup Spreadsheet Rows」では取得できる行が1行のため、翌月の発表全てというような複数行取得したい場合は「Lookup Spreadsheet Rows (Advanced)」を選択する必要があります。

4.Slack送信メッセージ作成

3で取得した要素をSlackのメッセージへ整形するためpythonで実装しています。

date_list=input_data['date'].split(',')
title_list=input_data['title'].split(',')
SlackID1_list=input_data['SlackID1'].split(',')

result = f'''
【{input_data['month']}月 Hacker’s Delightスケジュールのお知らせ】
{input_data['month']}月のスケジュールの予定はこちらです。発表者の方は準備をよろしくお願いします。
何かあれば @devrel へご連絡ください
'''

for i in range(len(date_list)):
    string = f"\n{date_list[i]}:{title_list[i]} <@{SlackID1_list[i]}>"
    result = result + string

print (result)

return {'result' : result}

それぞれの発表の部分はリストの要素分ループで回して戻り値へ加算(追記)していく形になっています。

5.Slackへ送信

4で整形したメッセージ(戻り値)をシンプルにSlackのチャンネルに送信しています。

実際に以下のようなメッセージが送信されます。 Zapの解説は以上になります。

おわりに

今回は1つのZapを用いて解説を行いましたが、11日目の記事で解説したインプットがあれば

  • 毎週月曜日に発表者へリマインドし、発表予定がなければ募集する
  • 発表があれば開始のアナウンスをし、発表予定がなければスキップのアナウンスをする

上記のようなリマインドも実装することができます。
また、今回エニグモで行っているアドベントカレンダーのリマインドも同じ要領で自動化しています。

スケジュールを把握して色々なメンバーにリマインドをするというのは思いの外意識を割かれてしまうため、
GoogleスプレッドシートとZapierが利用できる環境にあれば是非自動化にチャレンジしていただければと思います。

2記事に分かれて長かったですが、お読みいただきありがとうございました。
明日の担当はRDチームの廣島さんです。お楽しみに。


株式会社エニグモ すべての求人一覧

hrmos.co

GoogleスプレッドシートとZapierを用いた勉強会チームのリマインド自動化(Googleスプレッドシート編)

こんにちは!インフラエンジニアの森田です!

この記事はEnigmo Advent Calendar 2024の11日目の記事です。

私は社内の勉強会チーム(DeveloperRelationsチーム)としても活動しており、 人力で行なっていたリマインドをZapierで自動化したのでそのご紹介をしたいと思います。

今回は毎週金曜日に実施している軽い勉強会(Hacker'sDelight)のリマインドの自動化を例に記載します。

元々は以下のようなスケジュール管理シートがあり、こちらを人の目で見て翌月の発表者やその週の発表者にSlackでリマインドを送るという運用をしていました。

ただずっと人力でリマインドを送るというのはツラいため、社内で自動化ツールのZapierを契約しているため折角なら自動化してしまおうということで自動化に着手しました。
調べながらZapを作成する中で意外にZapierの日本語のドキュメントが少なかったため、この記事が備忘録かつ同じような自動化をやりたい方の参考になればと思います。

今回の自動化を構成しているのは大きく分けて以下の3要素になります。

  • スケジュール管理シート(パブリック)
  • リマインド管理シート(クローズド)
  • Zap

全ての要素の解説を1記事で行うと長くなってしまうため今回は「スケジュール管理シート」と「リマインド管理シート」の解説を行います。 Zapの解説は12日目の記事で解説したいと思います。

スケジュール管理シート(パブリック)

以下が「スケジュール管理シート」です。 基本的に上で貼ったスケジュール管理シートと同様ですが、「リマインド管理シート」でSlackIDをメールアドレスから自動検索するために列が追加されています。 こちらのシートは基本的にパブリックになっており、一般メンバーもHacker'sDelightのカレンダーとして見ることができます。 全て手動で管理しているので特に言及するところはありませんが、この後の解説で関連してくる列は以下となります。

  • 内容
  • 発表者1,2(敬称略)
  • 発表者1,2メアド
  • 日程

リマインド管理シート(クローズド)

「リマインド管理シート」は「Zapier通知用」と「Slackメンション用IDリスト」の2つのシートからなります。

Zapier通知用

このシートは「スケジュール管理シート」から参照した値から計算して自動的に埋められるため、手動での管理は不要になっています。 それぞれの列の解説をします。

  • 日程
  • 発表内容
  • 発表者1,2
  • 発表者1,2メアド

これらの列は全て「スケジュール管理シート」からそのまま参照しています。 別のスプレッドシートから値を参照してくるにはIMPORTRANGE関数を使用します。

例)
=IMPORTRANGE("https://docs.google.com/spreadsheets/d/xxxx","2025!G4")

また、発表者の部分は敬称をスプレッドシート側で入れておきたいのでカスタム数値形式で「@さん」と入れることで自動で敬称を付与するようになっています。

  • 開催月

MONTH関数を用いて何月に開催されるのかを抽出しています。 これは翌月の発表をまとめてリマインドするのに使用します。

例)
=MONTH(A2)
  • 当日までの日数

日程のセルからTODAY関数で今日の日付をマイナスすることで発表当日まで何日なのかを算出することができます。

例)
=A2-TODAY()
  • メンション用ID

VLOOKUP関数で「Slackメンション用IDリスト」から発表者メアドに対応した IDを取得してきています。 元々人力でメンション用IDを探してコピペしていましたが辛すぎるうえミスが分かりずらいため、IDは自動で取得されるようにした方が良いと思います。

例)
=VLOOKUP(F2,'Slackメンション用IDリスト'!$A$3:$B$1435,2,FALSE)
  • 開催フラグ

発表があるのかないのかを判別するためにISBLANK関数で発表内容のセルを空白判定しています。 また、そのままだと発表がある(セルが埋まっている)とFALSEと判定され違和感があるため、NOT関数で逆の論理値が返されるようにしています。

例)
=NOT(ISBLANK(D2))

Slackメンション用IDリスト

以下のドキュメントを参考にメンバーリストを取得すると、ユーザーのメールアドレスとUserIDが記載されたcsvファイルが取得できます。
ワークスペースのメンバーリストをダウンロードする

こちらのシートはcsvの内容をそのままコピペしたものです。 Zapierを使ってユーザーにメンションをする際にはこのUserIDが必要になります。
注意が必要なのはこのメンバーリストがSlackのオーナーまたは管理者権限を持っていないと取得できない点です。
不特定多数が見られる場所に書かれるのは好ましくないため、「リマインド管理シート」の参照権限はクローズドで必要のあるメンバーのみが見られるようにするべきです。

Zapierでリマインドを行うためのインプットとなるスプレッドシートの解説は以上となります。
明日の記事では実際にリマインドを行う部分であるZapの解説を行います。


株式会社エニグモ すべての求人一覧

hrmos.co

ruby-lspを少し便利にするruby-lsp-addons

この記事は

私は、株式会社エニグモでチームのマネージャをしている後藤です。 マネージャ業務の傍ら開発作業を行うこともあります。

この記事はEnigmo Advent Calendar 2024の10日目の記事です。

この記事では多くのRubyを使っている人が、使っているであろうruby-lspを少し便利にする ruby-lsp-addons について紹介しながら、VSCode でどのように活用できるのかについて紹介したいと思います。

ruby-lspとは

ruby-lsp とは、Ruby言語向けに Microsoft が定義している、Language Server Protocolを実装したサーバになります。

Language Server Protocol(以下 LSP) は、プログラム中に定義されたクラス名、関数名、変数名などを取得できるAPIとデータ型を定義したものになります。プログラム中のデータを取得するAPIを定義しておくことで、エディタから対象言語に対応した LSP サーバーを通して 関数定義情報を表示、関数/変数の定義箇所へのジャンプ、関数名/変数名を使った入力補間ができるようになります。

LSP の登場以前は universal-ctags + GNU Global などを用いて同様の機能を実現することが多かったように思いますが、VSCode の登場と合わせて LSP の提案と普及が進みました。その結果、多くのエディタで LSP がサポートされるようになり、最近は補間や関数ジャンプのための機能が LSP に集約されつつあるように思います。

Visual Studio Code(VSCode) の場合は、 ruby-lsp プラグインVSCode に追加することで rubyソース編集次に ruby-lsp を使った関数ジャンプや入力補間が使えるようになります。

ruby-lsp-addons

ruby-lsp ですが、当然ながら ruby の文法しかサポートしていません。ただ、Ruby on Rails の場合はモデルの has_many、blongs_to、validates などなど多数の DSL がありこれらもOUTLINEなどに表示して欲しいところですが、その機能を ruby-lsp に実装するのも違っている気がします。

そんな問題を解決しようとしているのが、 ruby-lsp-addons 機構になります。

公式のドキュメントは Add-ons | Ruby LSP にあります。ただ、公式ドキュメントにもあるように実験的な取り組みのようで、 ruby-lsp のメジャーバージョンが変わると、インターフェイスが変わって addons が動かなくなることもありますし、将来a addons のサポートが終わってしまう可能性があることを心にとめて置いてください。

それでは、

について紹介していきたいと思います。

ruby-lsp-rails

こちらの add-on を使えるようにするには、ruby-lsp-rails gem を追加します。

名前からわかる通り、rails 固有の機能サポートを追加するadd-onになります。 今回は、gitlabhq/gitlabhqのソースの一部を表示しながら、 公式ドキュメントからいくつかの機能を抜粋して紹介したいと思います。

modelのDSLサポート

# frozen_string_literal: true

module Achievements
  class Achievement < ApplicationRecord
    include Avatarable
    include StripAttribute

    belongs_to :namespace, inverse_of: :achievements, optional: false

    has_many :user_achievements, inverse_of: :achievement
    has_many :users, through: :user_achievements, inverse_of: :achievements

    strip_attributes! :name, :description

    validates :name,
      presence: true,
      length: { maximum: 255 },
      uniqueness: { case_sensitive: false, scope: [:namespace_id] }
    validates :description, length: { maximum: 1024 }

    def uploads_sharding_key
      { namespace_id: namespace_id }
    end
  end
end

のようなコードがあると、 VSCodeOUTLINE には以下のように Rails 固有の DSL で定義された項目も表示されます。

コントローラーメソッドからviewへのジャンプ

コントローラのメソッド画面にviewを開くリンクが追加されます。

上の絵の赤枠で囲ったリンクが表示されるようになります。 この、Jump to view をクリックすることで view が表示されます。 地味に、便利です。

その他の機能

公式ドキュメントを読むと、モデルの belongs_to のアソシエーション先にジャンプできる機能、コントローラーのメソッド定義箇所からルーターの定義にジャンプできる機能などがあることになっていますが、上手く機能していないようです。この辺は実験的な取り組みということを温かく見守ることしましょう。

ruby-lsp-rspec

次は、ruby-lsp-rspec です。 こちらも add-on を使えるようにするには、ruby-lsp-rspec gem を追加します。

こちらも名前から想像できる通り、 rspec 向けの機能拡張を行う add-on になります。

以下のような specファイルを開くと、

# frozen_string_literal: true

require "spec_helper"

RSpec.describe Diffs::StatsComponent, type: :component do
  include RepoHelpers

  subject(:component) do
    described_class.new(diff_files: diff_files)
  end

  let_it_be(:project) { create(:project, :repository) }
  let_it_be(:repository) { project.repository }
  let_it_be(:commit) { project.commit(sample_commit.id) }
  let_it_be(:diffs) { commit.raw_diffs }
  let_it_be(:diff) { diffs.first }
  let_it_be(:diff_refs) { commit.diff_refs }
  let_it_be(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs: diff_refs, repository: repository) }
  let_it_be(:diff_files) { [diff_file] }

  describe "rendered component" do
    subject { page }

    let(:element) { page.find(".js-diff-stats-dropdown") }

    before do
      render_inline component
    end
...

VSCodeOUTLINE に以下のように、 examples のテキストが表示されるため、 spec ファイルの流れを追うのも、修正をするのも楽になります。

また、以下のようにspecファイル上に Run | Run In Terminal | Debug リンクが追加されます。

このRunなどをクリックすることで、rspecのテストを実行できます。また、これらのテスト機構が、 VSCode の テスト機能に統合されているため、 以下のような VSCode 標準の、 Test: Run Test at Curosr などの機能が利用できるようになります。

また、テスト結果についてもGUIで表示られるようになります。

テスト結果がエラーになっているのは、DBなどを構築せずテストだけ実行したためで、gitlab のバグではありません。

使いたいんだけど、プロジェクトの Gemfiles に組み込めないんだけど

VSCoderuby-lsp ですが、インストール時の設定では、プロジェクトに bundle install されているものを使う設定になっていると思います。そのため、プロジェクトの他のgemとの依存関係の問題で使いたくても最新の ruby-lsp が使えない、なんて問題に出会う事があると思います。

そのような場合は、 ruby-lsp などの ruby 開発サポート系ツールだけをインストールしたリポジトリを準備し、bundler でインストールした bin ディレクトリへ PATH を通しておいて、 VSCode 上の設定を変更することで、プロジェクトは独立した形で、 ruby-lsp を使うことができます。

手順は以下のようなGemfileを準備し

# frozen_string_literal: true

source 'http://rubygems.org'


gem 'ruby-lsp'
gem 'ruby-lsp-rails'
gem 'ruby-lsp-rspec'

対象ディレクトリで、

bundle config path vendor
bundle install

しておき、VSCodesettings.json にいかの項目を追加します。

"rubyLsp.bundleGemfile": "${インストールディレクトリ}/Gemfile"

私の場合は、asdf を使ってrubyをいれているのもあってrubocop、erblint などをひとまとめにしたチェック系ツールをまとめたリポジトリを作り、homebrewとasdf用の環境セットアップをするラッパースクリプトを通して、bundle exec するシェルスクリプトから各種ツールを起動するリポジトリを作って使っています。

また、PCが変わっても VSCode の設定が変わらないよう上記リポジトリ

/opt/ruby_tool

へcloneしています。

参考のために、 ruby_toolへのリンクも貼っておきます。頻繁にバージョンを上げたり、ツールを入れ替えたりしているので、ご利用される際は、forkしてお使いください。

最後に

最後までお読みくださりありがとうございました。

明日の記事の担当は 森田 さんです。お楽しみに。

また、株式会社エニグモでは、ツールやエディタのカスタマイズを愛する人エンジニアもそうでないエンジニアも広く募集しております。興味のある方は、以下の求人一覧をご覧ください。


株式会社エニグモ すべての求人一覧

hrmos.co

データアナリストがネガティブなことを伝えなければならない時に気を付けていること

こんにちは、データアナリストの井原です。

この記事はEnigmo Advent Calendar 2024の9日目の記事です。

私は、普段データアナリストとしてエニグモで働いています。データからビジネスの意思決定を行うための示唆を出し、関係者に正しく伝えることが主要な業務です。

最近、チームの勉強会でも話題になったのですが、データアナリストは伝え方って大事だよねという話がありました。その場ではさらっと話が進んだのですが、確かに、データアナリストはいつもポジティブな結果ばかりを伝えるわけではありません。企画者が苦労をしてリリースにこぎつけた施策で、結果も期待されていてという状況で、数字がよくなかった、または、懸念点が上がってきたということも多いです。

この記事では個人のこれまでの経験を振り返って、ネガティブなことを伝えなければいけない時に、どのようなことに気をつけたらよいかを考えてみたいと思います。

この1年を振り返ってみても、結果を伝えにくいと思う案件はいくつかありました。「事前検証ではそれなりに効果が出そうであると(自分が)押した案件が、蓋を開けてみると効果はかなり微量だった。」「これまで重点的に企画が行われてきた施策について、利益性が低そうだと伝えなければいけなかった。」などなど。

そんな自分の経験を通して、どんなことに気を付けるとよさそうか、5つ洗い出してみました。挙げてみた要素はあくまでも個人の意見ではありますし、自分も常にうまくやれているわけではないのですが、自戒もこめて書いていきたいと思います。

1.言いやすい関係性を作っておく

いきなり、そもそもといった内容にはなりますが、元々の関係性はかなり重要な要素だと思います。 これは、言う側だけでなく言われる側の身を想像しても、それまで関係性の薄い第三者から言われるよりは、自身の取り組みを知ってくれている人の方が受け入れやすくなると考えられます。

そのためには、可能な限り、企画の段階でデータアナリストも企画に入っていけるようにするとよいと思います。また、分析の時点から入らざるを得ないとしても、こまめに質問や進捗を伝えるなどして、コミュニケーションを増やしておくといざという時には伝えやすくなります。

巨大な組織だと難しいところもあるかもしれませんが、エニグモは比較的少人数の組織なので、その辺りはやりやすい気はしています。

2.言葉遣いに気を付ける

当たり前ではあるのですが、伝える時の言葉遣いは気を付ける必要があります。特に意識をしていないと、さらっと否定的な言葉が(そこまで否定的だと意識せず)つい出てしまう場合があります。

例えば、「意味がない」とか「ダメですね」のような全否定の言葉は使わないように自分は気をつけます。「この数字だとちょっと厳しいかもしれません」や「想定と違うかもしれませんが、どうですか?」のような、相手と会話していく姿勢を出すだけでも建設的に話せるのではないかと思います。

前項とは反対になりますが、言いやすい関係を作りすぎてしまうと、ぽろっと否定的な言葉も出やすくなってしまう(気軽に話せるので言葉を意識しなくなりやすい)側面もあるので、この辺りはバランスを考えてうまく調整出来るとよいのではないかと思います。

3.最初に「言いづらい結果なのですが」と言ってしまう

これはテクニック的な話ではありますが、会議の最初に言ってしまうと、言う方も聞く方も受け入れる準備が出来るので楽になるのではないかと思います。あるいはタイミングがあれば、「今分析しているのですが、厳しい結果が出るかもしれません」と雑談的に話しておくのもよいでしょう。

根本的にはもう少し他の項目の方が大事ではないかとも思いますが、相手に結果を受け入れてもらうということも、アナリストの重要な仕事の一つです。こういった地味なテクニックを意識しておいて損はないと思います。

4.相手に労いと尊敬の気持ちを持つ

言葉遣いなどに繋がる話ですが、施策を進めているメンバーはその企画に対してかけた労力や思いがあります。その労力や思いに対しては、労いと尊敬の気持ちを持つことが大事です。

相手の企画に対しての思いを知る過程で関係性も作れると思いますし、言葉遣いも下手な言葉遣いはしにくくなると思います。例えば、相手が大切に思っていることに対して、「意味ないよ」などとは、ある程度の良識があれば言いにくいですよね。

5.それでも遠慮はしない、自分の分析結果には自信を持つ

相手を思いやることは大事だと思いますが、一方で、データアナリストとして伝えるべきことは伝えなければなりません。 そのため、最終的には自分の分析結果に対して自信を持つことも大事です。

伝えづらい分析結果が出てきた時、多くの分析者は分析内容を振り返ったり、よさそうな点を見つけようとデータをさらに詳細に区切って細かい分析を行ったりなど、よくあるのではないかなと思っています。しかし、持てる知識をフル活用して分析を行った結果なのであれば、下した結論がネガティブな内容であっても、それはしっかりと伝える必要があります。

伝え方自体は上で書いたように気を付ける必要がありますが、結論はしっかりと相手に伝わるように、準備できればよいと思っています。

おわりに

自分の一年間を振り返りつつ、ネガティブなことを伝えなければならない時に気を付けていること(きたこと)を洗い出してみました。 世の中には、データから新しい知見を発見して、それを活用して成功しました!というポジティブな話が多いと思いますが、現実のデータ分析では、新しい発見やポジティブな結果が確認できることばかりではありません。むしろ、特に目新しくない結果、ネガティブな結果が出てくる方が多いと思われます。

データアナリストという立ち位置は、時に第三者的な視点での意見が求められる職種ですので、データの解釈は冷静に客観的に行わなければなりません。しかし、それを伝えるところまで責任を持つという点では、合理性や客観性以外の人情的なコミュニケーションも必要になってくると思います。

少しでも、今回の話がデータを取り扱う方々の参考になったら幸いです。お読みいただきありがとうございました。

明日の記事の担当はエンジニアの後藤さんです。お楽しみに。


株式会社エニグモ すべての求人一覧

hrmos.co