Ruby,Windows,環境構築

2020/08/19 追記

こちらの記事が割と検索に引っかかってみてくれているようなので追記しておきます。
最近関連した記事を追加したので、よろしければこちらもどうぞ。
【Ruby/Win】Windows上のAtomからWSL2上のrubocopを利用する 2020年版

本文

こんにちは、しきゆらです。
今回は、Windows上でRubyの開発環境を整える方法をメモしておきます。

以前までは、DockerやWSLを使って開発ができそうな状態までをメモしてきました。
しかし、少し前に画期的なものがMicrosoftから発表されました。
そう、WSL2です。

以前までのWSL(以下、WSL1)から大きく改善され、個人的には普段使いできるのでは?という状態までなっています。
今回は、WSL2を導入してWindows上でRuby環境を構築、rubocopで変なコードを怒ってもらうところまでをまとめます。

Linux,Ruby,Windows

皆さん、Sinatra使っていますか?
簡単なWebアプリであれば一瞬でできてしまうような、Webアプリケーションフレームワークです。

しかし、簡単なので機能をたくさん増やしていたり、処理が多くなってくるとどうしても起こるのが「全体像が見えにくくなる」ということ。
機能やエンドポイントごとに分割したい、と思うこともあるでしょう。
私は思いました。
その方法を調べてみたので、まとめておきます。

例として、以下のような形でアプリケーションを作成しているとします。

[ruby]
# app.rb
require 'sinatra’
class MyApp < Sinatra::Application
get '/’ do
'hello’
end
end
[/ruby]

今回は、エンドポイントごとにファイルを分割していきます。

 

Ruby,Windows

こんにちは、しきゆらです。

タイトルが長くてよくわからないかもしれません。
問題と解決方法を、メモしておきます。

問題

WSL上にrbenvを用いてRuby2.6.3をインストールして簡単なWebアプリを作成しようとしていました。
適当なディレクトリにbundlerを使ってSinatraとUnicornをインストールし、起動テストを行いました。
最初は問題なくUnicornが起動したので、一度停止させておきました。
再びUnicornを立ち上げると、うまく立ち上がりません。

Unicornはデフォルトではターミナルにエラー等を表示しないので、エラーログをファイルに吐き出すようにしてありました。
エラーログの中には、このようなエラーが記録されていました。
code:error
F, [2019-05-22T22:52:13.998205 #22482] FATAL — : error adding listener addr=/path/to/sinatra_app/tmp/sockets/unicorn.sock
ArgumentError: socket=/path/to/sinatra_app/tmp/sockets/unicorn.sock specified but it is not a socket!

どうやら、ソケットファイルが問題のようです。

解決方法

根本的な解決方法ではありませんが、tmp/sockets/unicorn.sockファイルを削除すると問題なく起動するようになりました。

しかし、再度Unicornを停止した後Unicornを再起動すると再び上記のエラーが表示されます。
Unicorn停止とsockファイルの削除は同時に行うと、無駄な時間がかからないかともいます。

解決方法があればコメントやTwitter等から教えてほしいです。
というか、そもそもsockファイルと普通のファイルの違いなどもきちんと理解できているわけではないので、この辺も含めて調べる必要がありそうです。

今回は、場当たり的な対処法までをまとめておきました。

 

おわり

Ruby

こんにちは、しきゆらです。
今回はタイトルの通り、Rubyで文字列を判定するときに大文字小文字を無視して判定する方法を知ったのでメモしておきます。

記述としては、

[ruby]
/Test/i
[/ruby]

と記述することで

  • test
  • Test
  • TEST

など、大文字小文字を無視して判定してくれるようです。

Rubyの正規表現ページにも書いてありました。
きちんと見ないといけないなぁと、何度目かの反省でした。

 

おわり

Ruby

こんにちは、しきゆらです。
今回は、タイトル通りものづくりの中でよく使うであろうrootパスを取得する方法をメモしておきます。

といっても、今回は「すべてのコマンドや実行はrootディレクトリから行う」という方針で考えています。
これを決めておけば、簡単です。

方法

すべてrootディレクトリから行うと決めてしまえば、難しいことはありません。
RubyさんはDirというディレクトリ操作のためのクラスや、Pathnameというパス名操作のためのクラスがあります。
これらを使えばよいですね。

pwd -> String
カレントディレクトリのフルパスを文字列で返します。

https://docs.ruby-lang.org/ja/latest/method/Dir/s/getwd.html

class Pathname
パス名をオブジェクト指向らしく扱うクラスです。

https://docs.ruby-lang.org/ja/latest/class/Pathname.html

コードは以下の通り。

ROOT_PATH = Pathname.new(Dir.pwd)

Dir.pwdは作業中のディレクトリを取得できるので、Pathnameで囲んでおきます。
これを定義しておけば、読み込みたいファイルをjoinでつなげていけばいいので便利。

 

まとめ

今回は、rootパスを取得する方法をメモしました。
といっても、コマンド実行しているディレクトリをrootパスとして決め撃ちしているので本来の指定方法ではないのかもしれません。

いい方法があれば教えてください。

 

今回は、ここまで。
おわり

Ruby

こんにちは、しきゆらです。

今回は、タイトル通りmysql2のインストールに失敗したのをなんとかする方法をメモしておきます。

 

環境としては、

  • Mac
  • Ruby2.6.0
  • Rails5.2.2
  • MySQL8.0.13

という状態。

 

普通にbundle installすると、エラーが。

Fetching mysql2 0.5.2
Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/user_name/path/to/vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.2/ext/mysql2
/usr/local/Ruby/bin/ruby -I /usr/local/Ruby/lib/ruby/2.6.0 -r ./siteconf20181231-27997-6j2jh2.rb extconf.rb
--with-ldflags\=-L/usr/local/opt/openssl/lib\ --with-cppflags\=-I/usr/local/opt/openssl/include
checking for rb_absint_size()... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/usr/local/Ruby/bin/$(RUBY_BASE_NAME)
/usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:467:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:552:in `try_link0'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:570:in `try_link'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:782:in `try_func'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:1069:in `block in have_func'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:959:in `block in checking_for'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:361:in `block (2 levels) in postpone'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:331:in `open'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:361:in `block in postpone'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:331:in `open'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:357:in `postpone'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:958:in `checking_for'
    from /usr/local/Ruby/lib/ruby/2.6.0/mkmf.rb:1068:in `have_func'
    from extconf.rb:25:in `<main>'

To see why this extension failed to compile, please check the mkmf.log which can be found here:

/Users/user_name/path/to/vendor/bundle/ruby/2.6.0/extensions/x86_64-darwin-18/2.6.0-static/mysql2-0.5.2/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in
/Users/user_name/path/to/vendor/bundle/ruby/2.6.0/gems/mysql2-0.5.2 for inspection.
Results logged to
/Users/user_name/path/to/vendor/bundle/ruby/2.6.0/extensions/x86_64-darwin-18/2.6.0-static/mysql2-0.5.2/gem_make.out

An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2

mysql2のインストールに失敗したようです。

調べてみると、以下のような解決方法がいくつも提示されていました。

 

以下のコードを打ち込む。

bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include

RailsにMySQLを導入したらかなりハマった件について – 大学生Webエンジニアの記録

 

調べてみると、どうやらbundlerにはgemをビルドするときにフラグやオプションを渡すことができる機能を持っているようです。

上記コードは、mysql2のビルドオプションを渡すコードのようです。

Build Options

You can use bundle config to give Bundler the flags to pass to the gem installer every time bundler tries to install a particular gem.

bundle config build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config

Bundler: bundle config – Bundler Docs

 

似たコードが書かれています。

オプションを追加し、再びbundle install。

・・・エラー直らず。

 

途方に暮れていると、こんな情報が。

ログ見たら –with-cppflags オプションに対応してないとのこと。
ldflagsのみで実行してみる

bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"

mysqlのbundle installに失敗する – Qiita

 

なんと、cppflagsはいらないようです。

実際、上記の設定後にbundle install すると問題なくインストールできました。

$ bundle install
...
Fetching mysql2 0.5.2
Installing mysql2 0.5.2 with native extensions
Fetching pry 0.12.2
...

 

 

先人たちの体験談には頭が上がりません。

感謝です。

 

 

今回はここまで。

おわり

Mac,Ruby

こんにちは、しきゆらです。

毎年、この時期はRubyの最新版リリースが熱いですよね。

ということで、早速環境を作っていきましょう。


Rubyは、Ruby3x3という目標のもと、高速化のための改良が続けられています。

今回は、高速化のための変更としてJITコンパイラが導入されました。

オプションとして–jitをつけると、JITを使って動作するようです。

詳しい更新内容については、以下を参照して下さい。

高速化以外の変更でよく使いそうなものとしては、「終端なしRange」の追加でしょうかね。

あとは、何気にCSVファイルの扱いも高速になっているようです。

さて、それでは実際にコンパイルしてみて、どのくらい早くなったのかを、簡単なベンチマークを取りながらみてみましょう。

Ruby

こんにちは、しきゆらです。

今回はExcelで書き出したCSVファイルをRubyで読み込むときに躓いたところをメモしておきます。

 

状況

Excelで管理していたとあるデータをCSVで書き出し、Rubyで変換しつつDBへ突っ込もうと思っていました。

CSVファイルは、先頭にヘッダーとなるタイトルをつけていて、2行目からが実質のデータでした。

 

ExcelでCSVファイルを吐き出す

Excelで書き出すことができるCSVファイルは2種類あります。

  • 「一般的な形式」の中にある「CSV UTF-8 (コンマ区切り) (.csv)」
  • 「特別な形式」の中にある「CSV (コンマ区切り) (.csv)」

「特別な形式」では、文字コードがShift-JISのため「一般的な形式」の方で吐き出しました。

あとは、RubyのCSVライブラリで読み込んでforeachなどですべての行を読み込めば終わり。

・・・と思っていた時代が私にもありました。

このUTF-8が曲者でした。

 

詳しくは、続きから。

 

Ruby

こんにちは、しきゆらです。

今回は、タイトル通りですが、GoogleのAPIを利用したアプリケーションを作るときの流れを見ていきます。

大まかな流れとしては、以下のとおりです。

  • Google Cloud Consoleから、APIを有効にする
  • APIを叩くための認証を通す
  • 認証情報をもとに、APIを叩く

では、それぞれ見ていきます。

Ruby,Slack

こんにちは、しきゆらです。

前回・前々回とSlackとのやり取りをさっくりと確認していました。

前回の記事

【Ruby】Slack Botことはじめ

前々回の記事

【Ruby】Slack Appことはじめ

タイトルが似ているので間違えそうですね・・・。

Slack AppがBotも含んだ広い意味でのSlack上で動くアプリ全般を表しています。

Slack BotはAppの中でもBotとして振る舞うようなアプリを指しています。

 

今回は、Slack Botでもう少し複雑なこともしたいので、RTMを利用してみます。

 

RTMとは?

タイトルにもある通り、Real Time Messaging APIの略で

Slackと常に接続し、ユーザの動きを監視して特定の行動が起こったら反応する、というようなことができるAPIです。

例えば、

  • ユーザが入力を始めたとき、通知する
  • メッセージが変更されたとき、前後の差分を表示する

などができそうです。

この辺は発想次第でなんとでもできそうですね。

 

では、実際に使って行きます。