- 投稿日:2019-07-24T23:00:15+09:00
Rails 5.1.6 デフォルトのGemfileを調べる
作成時にデフォルトで入っているGemfile
Gemfilesource 'https://rubygems.org' git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") "https://github.com/#{repo_name}.git" end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.1.6' # Use sqlite3 as the database for Active Record gem 'sqlite3' # Use Puma as the app server gem 'puma', '~> 3.7' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' # See https://github.com/rails/execjs#readme for more supported runtimes # gem 'therubyracer', platforms: :ruby # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2' # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.5' # Use Redis adapter to run Action Cable in production # gem 'redis', '~> 4.0' # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] # Adds support for Capybara system testing and selenium driver gem 'capybara', '~> 2.13' gem 'selenium-webdriver' end group :development do # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. gem 'web-console', '>= 3.3.0' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]各Gemfileの内容
一般
rails : rails一般
sqlite3 : db管理SQLite3 (local環境で使う herokuではpostgreSQL)
puma : アプリケーションサーバー
sass-rails : css (railsでまとめた表現ができる)
uglifier : JavaScript 改行や空白を削除して軽量化
(#)therubyracer : JavaScript mini_racerのほうが良い???
coffee-rails : CoffeeScriptをRailsで使用 (CofferScripはJavaScriptを簡潔にした言語)
turbolinks : ブラウザのページ移動を高速化 (ページ遷移で変化のあるhtml要素のみを変更する)jbuilder : 入力データをJSON形式で出力
(#)redis : セッションを保存するときに使用???
bcrypt : BCryptを用いてパスワードを暗号化
(#)capistrano-rails : 複数のサーバーへのデプロイを自動化group :development, :test
byebug : コードの途中に書けばそこで止まる(byebug unless ~)
capybara : rubyのウェブアプリケーションテスト
selenium-webdriver : 自動でブラウザを動かしテストするgroup :development
web-console : ブラウザ上からコンソールを操作するライブラリ
windows用
tzinfo-data : タイムゾーンを扱うライブラリ (windowsではこれを含める必要がある)
参照
- 投稿日:2019-07-24T21:56:14+09:00
既存のRuby on RailsプロジェクトにJenkins と Docker で CIを導入する
要約
引き継いだプロジェクトなどで既存のRailsアプリにCIがない場合に、気軽にテストを書いてCIを回す文化を醸成したいと思って対応した内容の記録です。
対象読者
Railsのプロジェクトを運用している方で、引き継いだプロジェクトなど何からの事情によりテストを書く環境がない、または、CI環境を構築したいが、日本語の情報が少ない(自分がそうでした)ために構築に苦労している方に向けた記事です。
構成
構築手順
1. ビルドマシンの準備
- 適当なLinuxマシンを用意してください。
- 今回の例ではCentos7を使用しています。
2. dockerインストール
- 公式の記述に従い最新版のインストールします。
- https://docs.docker.com/install/linux/docker-ce/centos/
3. docker-composeインストール
- こちらも公式より最新版のインストールを行います。
- https://docs.docker.com/compose/install/
4. Jenkins(スタンドアロン版)のインストール
- Jenkinsもdockerに閉じ込めたかったのですが、コンテナ上でdocker-compose の使用がうまく動かなかったため、今回はやむなくJenkinsだけは ビルドマシン上にwar配置という形をとりました。
# Jenkinsの起動スクリプト作成 $ mkdir ~/myjkdir $ cd myjkdir $ wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war . $ cat <<EOT> start_jk.sh JENKINS_JAVA_OPTIONS="-Xmx2048m -XX:MaxPermSize=512m -Dorg.jenkinsci.plugins.durabletask.BourneShellScript.LAUNCH_DIAGNOSTICS=true" nohup java -jar jenkins.war & EOT $ chmod +x start_jk.sh $ chown $USER:$USER start_jk.sh5. Railsにビルド用の各種設定を行う
- railsアプリをdockerにのせるための手順はこちらの通りで動作しました。
- https://docs.docker.com/compose/rails/
- ※ 後述していますが、この際、採用するイメージのミドルウェアのバージョンは実際に使用しているものに合わせるようにしましょう。コピペで進むとビルド出来ないなど後々不安定な挙動に悩むことになります。
6. ビルドマシンでdocker-composeのイメージビルド
# 適当なディレクトリに上記リポジトリをチェックアウトして、dockerイメージのビルド cd /myapp_dir # Checkout from SCM . docker-compose build docker images # エラーなく、イメージがビルドできていることの確認 docker-compose up # コンテナ起動確認 docker-compose run web bundle exec rake db:create7. Jenkinsファイルの用意
pipeline { agent any stages { stage('build') { steps { sh 'echo "Hello World"' } } stage('test') { steps { sh 'docker-compose run web bundle exec rake db:create' sh 'docker-compose run web bundle exec rake db:schema:load' sh 'docker-compose run web bundle exec rake test test/**/*.rb' } } } }
- 参考: https://medium.com/capital-one-tech/super-powering-your-enterprise-jenkins-ci-pipeline-with-docker-compose-a4f508598375
- Thank you https://medium.com/@dariendford !!
8. Jenkinsでビルドジョブ(pipeline)を作成し実行
- 無事ビルド完了。 これで、テストを書いていけば自動テストが回りデグレの防止などコード品質向上に 寄与してくれることでしょう。 私も安心して眠れます。(テストを書いてから寝ろ)
はまったポイント
以下では、上記CI環境構築の間にハマったポイントを記載します。
1. 既存アプリのミドルウェアバージョンを良く確認しましょう。
- レガシーなプロジェクトだと、使用しているソフトウェアのバージョンが古いこともあり、 公式等の記述コピペで進むとうまく動かない状況に陥ります。 docker imageに採用するタグ(バージョン)を良く確認しましょう。
※ 例えばruby2.3とpostgres9.4の組み合わせのシステムの場合
- Dockerfile
FROM ruby:2.3 ...
- docker-compose.yml
db: image: postgres:9.4 ...2. docker関連ファイルの改行コードはLFで統一
- Windowsでの作業で意図せずCRLFが混入すると、dockerがエラーを出力しますのでご注意ください。
- 私はこれで半日溶かしました。
- https://forums.docker.com/t/getting-panic-spanic-standard-init-linux-go-178-exec-user-process-caused-no-such-file-or-directory-red-while-running-the-docker-image/27318
- 特にDockerfileのEntrypointに指定するコードの改行コードが問題を引き起こすことが多いようです。
所感
テストが気軽にかける環境をローコストで手に入れることはソフトウェア品質向上に寄与すると思っています。Rails単体でも、かなり簡単にテストができる仕組みが入っていると思いますが、さらにDB回りやシステム全体のビルドテストとなると、Dockerみたいなアプリをパッケージにできる仕組みで手軽に作って捨てる環境を作りたいところですが、現状まだまだ設定が煩雑だったり日本語情報が少なかったりと、環境構築に障壁を感じました。少しでもこの記事が同じような境遇の方のお役に立てば幸いです。
- 投稿日:2019-07-24T20:53:52+09:00
[Ruby] String#gsub で半角カタカナを全角カタカナに変換する
方法
コード
'タピオカ'.gsub(/[\uFF61-\uFF9F]+/) { |str| str.unicode_normalize(:nfkd) } #=> "タピオカ"説明
'タピオカ'.unicode_normalizeと書かずに gsub を介しているのは、Unicode 正規化を適用する文字列を限定し、想定外の置換が起きないようにするため。- 半角カタカナの Unicode コードポイントについては、@scivola さんのコメント、および Wikipedia の 半角カナ ≫ Unicode (UTF-8, UTF-16 など) を参考にした。
旧方法
@scivola さんにコメントをいただく前に紹介したいた方法。半角カタカナ以外も Unicode 正規化してしまうため改善が必要だった。
コード
'カンダタ'.gsub(/\p{In_Halfwidth_and_Fullwidth_Forms}+/) { |str| str.unicode_normalize(:nfkd) } #=> "カンダタ"説明
- Ruby の正規表現では
\p{}で Unicode プロパティを指定できる。
- 指定可能な Unicode プロパティの一覧は Onigmo/doc/UnicodeProps.txt1 を参照すること
- 半角カタカナや半角濁点・半濁点は Halfwidth and Fullwidth Forms に属している。
関連
参考
Unicode 正規化について復習するのに以下のページが役立った。
- 投稿日:2019-07-24T20:50:56+09:00
RailsでPostGISなカラムに値を入れる
TL;DR
PostGIS入れてactiverecord-postgis-adapter入れてgeometry型カラムを持つモデル作ったけどRailsでどうやって値入れるんだっけ?
→これでいけそう。RGeo::Geographic.spherical_factory(srid: 4326).point(139.7003912, 35.6897376)環境
mac OS X mojave
Ruby on Rails 5.2.3検証
- PostgreSQLをインストール(PostGISも)
$ brew install postgresql $ brew install postgis $ brew services postgresql start
- Railsプロジェクトを立ち上げ、
activerecord-postgis-adaptergemを追加$ rails new test_application $ cd test_application $ echo "gem 'activerecord-postgis-adapter'" >> Gemfile $ bin/bundle
- DBを初期化
$ bin/rails db:create $ bin/rails db:gis:setup
- モデルを作成
$ bin/rails g model Location name:string point:geometry #geometry型でモデルを作成 $ bin/rails db:migrate
- db/seed.rb にLocationモデルを作成
- SRID: 4326 は世界測地系のSRIDの一つ
- SRIDについては こちらを参考にしました
Location.create( name: "新宿駅", point: RGeo::Geographic.spherical_factory(srid: 4326).point(139.7003912, 35.6897376) )
- DBに値が挿入されていることを確認
$ bin/rails c irb(main):001:0> Location.all => #<ActiveRecord::Relation [#<Location id: 1, name: "新宿駅", point: #<RGeo::Cartesian::PointImpl:0x3fcd7929c4e0 "POINT (139.7003912 35.68973764)">>]>
- 投稿日:2019-07-24T20:11:00+09:00
database名を変更したい時
database名を変更したい時
復習のためにアプリを何個も作成していると、同じ名前のデータベースを作成してしまってエラーになってしまうのを避ける方法。
terminalDatabase 'sample1_development' already exists Database 'sample1_test' already existsデータベースはconfig/database.ymlに基づいて作成されます。
そのため、この中の記述を変えてあげればいいのです。
database.yml# MySQL. Versions 4.1 and 5.0 are recommended. # # Install the MYSQL driver # gem install mysql2 # # Ensure the MySQL gem is defined in your Gemfile # gem 'mysql2' # # And be sure to use new-style password hashing: # http://dev.mysql.com/doc/refman/5.0/en/old-client.html development: adapter: mysql2 encoding: utf8 database: sample1_development pool: 5 username: root password: # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: adapter: mysql2 encoding: utf8 database: sample1_test pool: 5 username: root password: production: adapter: mysql2 encoding: utf8 database: sample1_production pool: 5 username: root password:database:の後の
database: sample1_developmentを
database: sample2_development_testも同様に
変えてあげれば、rake db:createできます。
- 投稿日:2019-07-24T18:21:17+09:00
【Ruby 2.4.6 update】ArgumentError: key must be 32 bytes への、versionを動かさない対処
背景
Ruby 2.3.1 -> 2.4.6 へversion upしたら、ActiveSupport::MessageEncryptor周りでエラーがでた。
この中で使われているOpenSSLがもともと32bytes以上でも受け入れていたところを、32バイトぴったりしか受け付けなくなったのが原因の様子。
これが修正のcommit
データベースに32バイトより大きいkeyで暗号化したデータが入っていたので、それらをdecryptできなくて落ちていた。
ちなみにRailsは4系。捕捉
Rails 5.0.0.1 で対応が入っているらしい
https://github.com/rails/rails/pull/25192/files
でも今回はRailsのversionは上げられないので別の対処法を探す。
色々調べた感じ、多くの人はRubyのversionを戻したりとversionを上げ下げしてこの問題を回避してそうだった。解決案その1
Ruby 2.3系に戻し、32バイトより大きいkeyでdecryptして、32bytesでまたencryptする。
これでもいいのですが、ちょっと時間がかかりそう。解決案その2
32バイトっていうので、とりあえず32bytesにしてみた。
しかしdecryptで失敗。
これはchiperの方はsecretを32bytesに切ってくれるが、復号で使うverifierの方はそのままの長さを使ってるからのが原因の模様。d = ActiveSupport::MessageEncryptor.new(some_key[0..31]) rb(main):005:0> d.encrypt_and_sign("hoge") => "K3dtYVJUL1NucVpnRUFJWm9OZ3VQQT09LS1SMlRKb3dWWXFFajZ5MDFMcHQ3NmxRPT0=--910efa18ef525a38f7bf2482e94a54ec39ad1e65" d = ActiveSupport::MessageEncryptor.new(some_key[0..31]) irb(main):003:0> d.encrypt_and_sign("hoge") ArgumentError: key must be 32 bytesしかし、
ActiveSupport::MessageEncryptorのコードを読んでいたら、optionsで渡せそう。
option引数の先頭で渡せば@sign_secretに入って、そっちが優先されてverifierが作成される。#=> ActiveSupport::MessageEncryptor def initialize(secret, *signature_key_or_options) options = signature_key_or_options.extract_options! sign_secret = signature_key_or_options.first @secret = secret @sign_secret = sign_secret @cipher = options[:cipher] || 'aes-256-cbc' @verifier = MessageVerifier.new(@sign_secret || @secret, digest: options[:digest] || 'SHA1', serializer: NullSerializer) @serializer = options[:serializer] || Marshal endつまりこうすれば良い。
ActiveSupport::MessageEncryptor.new(some_key[0..31], some_key)急ぎだったので、解決案2で解決しました。
salt使うように修正予定。終わり
ベテランの方に助けてもらいました
ライブラリのコードリーディング力を高めなければ
- 投稿日:2019-07-24T18:00:30+09:00
Rubyでpackage-private的な可視性を実現する
TL;DR
private_constantというのを使えば定数のスコープを private にできるらしいのでそれを使う。
恥ずかしながら今まで知らなかった。Ruby でも静的型検査したい
と思ってる人が世の中にどれくらいいるかわからないけど、そういうライブラリが出てきたり(僕は sorbet を使ってみている)、Ruby 3 からは静的型が使えるだのなんだのっていう情報も飛び交っったりしていて、ダックタイピングを前提にコードの設計を考えないといけなかった今までとは若干趣が変わってきたかもしれないなぁと思っている。
ただ不満なのは、静的に型付けしてくれてもすべての型がグローバルだとどこを疎結合にしたいとかどこは凝集度が高いと考えいているかっていうのをコードレベルで表現できないし、最悪いろいろなものをバイパスされてしまう 1 ので、Java で言うところの pckage-private 的な可視性を使いたいなと思った。
module UserPackage class User def initialize(first_name, last_name) @first_name = first_name @last_name = last_name end end class FirstName def initialize(value) @value = value end end class LastName def initialize(value) @value = value end end end first_name = UserPackage::FirstName.new('Akira') #=> UserPackage 外でインスタンス生成できる last_name = UserPackage::LastName.new('Suenami') #=> UserPackage 外でインスタンス生成できる user = UserPackage::User.new(first_name, last_name)
UserPackage::Userはいわゆる集約のルートオブジェクトで、その内部に持つ 2 つのバリューオブジェクトUserPackage::FirstNameとUserPackage::LastNameはルートオブジェクトを通してのみ参照を渡したいとする。そういう場合、定数のスコープを private にする
private_constantというのがあって、それを利用して以下のようにする。# typed: strong require 'sorbet-runtime' module UserPackage class User extend T::Sig sig {params(first_name: FirstName, last_name: LastName).void} def initialize(first_name, last_name) @first_name = T.let(first_name, FirstName) @last_name = T.let(last_name, LastName) end sig {params(first_name: String, last_name: String).returns(User)} def self.factory(first_name, last_name) first_name = FirstName.new(first_name) last_name = LastName.new(last_name) new(first_name, last_name) end end class FirstName extend T::Sig sig {params(value: String).void} def initialize(value) @value = T.let(value, String) end end class LastName extend T::Sig sig {params(value: String).void} def initialize(value) @value = T.let(value, String) end end private_constant :FirstName private_constant :LastName end # first_name = UserPackage::FirstName.new('Akira') #=> private constant UserPackage::FirstName referenced (NameError) # last_name = UserPackage::LastName.new('Suenami') #=> private constant UserPackage::LastName referenced (NameError) # user = UserPackage::User.new(first_name, last_name) user = UserPackage::User.factory('Akira', 'Suenami')こんな感じになる。ついでに sorbet の型注釈もつけてみたのと、
UserPackageの外にはコンストラクタの引数に渡す型(FirstNameLastname)が公開されなくなったのでプリミティブ型からインスタンスを作るためのfactoryメソッドを作った。これでバリューオブジェクトはUserPackagemodule の外からは完全に見えなくなった感じ。定数の定義後じゃないと
private_constantの宣言は効かないっぽいので、実業務ではファイルのロード順とか気にしとく必要はありそう。ほとんどの場合は AcitveSupport の autoload に任せることになると思うので、該当のバリューオブジェクトを定義したファイルのクラス定義直後に書けば概ね問題ないとは思う。まとめ
特にない。僕自身も実際のプロダクトではまだやってないので、もし懸念とかあれば誰か教えて欲しい。
感覚的には結構いいのでは?っていう気がしている。2019/07/24 19:57 追記
なんか ActiveSupport の autoload だとあまりうまくいかなさそうですね…
https://github.com/rails/rails/issues/25813
https://github.com/rails/rails/issues/35898こちらうまく回避できないですかね…(調べてみる)
そんなやつをチームに入れるなという主張もあると思うが、それは別の問題なのでここでは扱わない。 ↩
- 投稿日:2019-07-24T15:14:45+09:00
参考リンク: RailsでViewを扱う方法
[Rein: RailsのActiveRecordでDB制約やデータベースビューを使えるgem(README翻訳)]https://techracho.bpsinc.jp/hachi8833/2017_09_11/45365
MySQLで利用できるかどうかなど未調査
※ 追記
ViewのCreateとApplicationRecordの利用はMySQLでも大丈夫でした
- 投稿日:2019-07-24T12:44:30+09:00
Rails6 のちょい足しな新機能を試す58(ActiveRecord::Errors#of_kind?編)
はじめに
Rails 6 に追加されそうな新機能を試す第58段。 今回は、
ActiveRecord::Errors#of_kind?編です。
Rails 6 にActiveRecord::Errors#of_kind?メソッドが追加されました。Ruby 2.6.3, Rails 6.0.0.rc1, PostgreSQL 10.7 で確認しました。Rails 6.0.0.rc1 は
gem install rails --prereleaseでインストールできます。$ rails --version Rails 6.0.0.rc1User モデルを作る
User モデルを作ります
$ bin/rails g model User nameUser モデルを修正する
validation を追加します。
app/models/user.rbclass User < ApplicationRecord validates :name, presence: true endrails console で確認する
rails consoleを実行して確認します。irb(main):001:0> user = User.new => #<User id: nil, name: nil, created_at: nil, updated_at: nil> irb(main):002:0> user.validate => false irb(main):003:0> user.errors.of_kind?(:name) => false irb(main):004:0> user.errors.of_kind?(:name, :blank) => true irb(main):005:0> user.errors.of_kind?(:name, "can't be blank") => true irb(main):006:0> user.errors.of_kind?(:name, :presence) => false試したソース
試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try058_errors_of_kind参考情報
- 投稿日:2019-07-24T11:50:45+09:00
macOS Mojave で RMagick gem を使う 2019年7月編
macOS を Mojave にアップグレードしたら
bundle installで RMagick が入らないよ!
またかよ。
(OS アップグレードのたびに起きるあれの解決策。)前提環境
$ ccを実行して command not found だったら、Xcode commndline をインストールする。
$ xcode-select --install原因
Homebrew で ImageMagick v.7 が入ったのが原因。RMagick は v.7 非対応。(2019-07現在)
https://github.com/rmagick/rmagick/issues/256$ brew uninstall imagemagick $ brew install imagemagick@6 $ brew link imagemagick@6 $ gem install rmagick # (または bundle install)
- 投稿日:2019-07-24T10:08:49+09:00
ruby で nl80211を使う
ruby からLinuxのnl80211を使ってみました。
nl80211を使ってWi-Fiのチャンネル設定をしてみました。
Ruby で Linux の NETLINKを使うの続きです。
nl80211はgenric netlinkという仕組みを使います。
socket生成
optionにNETLINK_GENERICを指定します。
require 'socket' module Linux NETLINK_GENERIC = 16 end class Socket PF_NETLINK = 16 unless defined? Socket::PF_NETLINK AF_NETLINK = PF_NETLINK unless defined? Socket::AF_NETLINK end s = Socket.new(Socket::AF_NETLINK, Socket::SOCK_DGRAM, Linux::NETLINK_GENERIC)リクエスト生成
チャンネル設定の場合、リクエストはnlhdr, genlhdr, IFINDEXのアトリビュート、 WIPHY_FREQのアトリビュート、 WIPHY_CHANNEL_TYPEのアトリビュートを含みます。
IFINDEXが4, 周波数が 6ch (2437MHz), バンドが2.4GHzの場合のリクエストです。
nlhdr = [24, 0x16, Linux::NLM_F_REQUEST | Linux::NLM_F_ACK, 0, 0].pack("ISSII") genlhdr = [Linux::NL80211_CMD_SET_WIPHY, 0, 0].pack(SSI) if = [8, NL80211_ATTR_IFINDEX, 4].pack(SSI) freq = [8, NL80211_ATTR_WIPHY_FREQ, 2437].pack(SSI) freq_type = [8, NL80211_ATTR_WIPHY_CHANNEL_TYPE, 0].pack(SSI)リクエスト送信、レスポンス受信
s.send(nlhdr+genlhdr+if+freq+freq_type, 0) resp = s.recv(4096)調査方法
iw を --debug 付きで動かしてみるのが良いです。
root@kali:~# iw --debug dev wlan0 set channel 6 -- Debug: Sent Message: -------------------------- BEGIN NETLINK MESSAGE --------------------------- [NETLINK HEADER] 16 octets .nlmsg_len = 44 .type = 22 <0x16> .flags = 5 <REQUEST,ACK> .seq = 1495358371 .port = 1413498624 [GENERIC NETLINK HEADER] 4 octets .cmd = 2 .version = 0 .unused = 0 [PAYLOAD] 24 octets 08 00 03 00 04 00 00 00 08 00 26 00 85 09 00 00 ..........&..... 08 00 27 00 00 00 00 00 ..'..... --------------------------- END NETLINK MESSAGE --------------------------- -- Debug: Received Message: -------------------------- BEGIN NETLINK MESSAGE --------------------------- [NETLINK HEADER] 16 octets .nlmsg_len = 36 .type = 2 <ERROR> .flags = 0 <> .seq = 1495358371 .port = 1413498624 [ERRORMSG] 20 octets .error = 0 "Success" [ORIGINAL MESSAGE] 16 octets .nlmsg_len = 16 .type = 22 <0x16> .flags = 5 <REQUEST,ACK> .seq = 1495358371 .port = 1413498624 --------------------------- END NETLINK MESSAGE ---------------------------ドキュメントがないので地道にしらべないと理解できないです。
あとで調査するかも
* authenticate
* associate
* send_mlme
* set_ap_wps_ie
- 投稿日:2019-07-24T00:32:18+09:00
Ruby yieldとは
yieldとは
ブロック付きメソッドでブロックを呼び出すことができます。
ブロックとは
do~end や {} で囲まれた処理のかたまり
以下の処理だと「puts i」の部分をブロック
「|i|」をブロックパラメータと呼ぶ(1..10).each do |i| puts i end例1
ブロックを実行する
def hoge yield end hoge do puts "^o^" end =>^o^def fuga yield end fuga{ puts ";o;" } =>;o;例2
yieldを複数回記述すると複数回実行される
def hogehoge yield yield end hogehoge do puts "hoge" end =>hoge hoge例3
ブロックなしでyieldを利用した場合
def fugafuga yield end fugafuga =>LocalJumpError (no block given (yield))
- 投稿日:2019-07-24T00:28:34+09:00
Githubでファイルを開く、該当行のPullRequestを開くスクリプトを作った
背景
業務で下記のようなことをしたい!、というような場面ってありませんか?
- 今エディタで開いているファイルをGithub上で開きたい
- 今エディタで見ている行を変更したPullRequest(以下PR)を確認したい
- PRを確認しないと、なぜそういう変更になったのか等の背景が分からないですよね
- PRが分かれば、だいたい元issueにもたどり着けますよね
VSCodeだと簡単にGithubに飛べますよね。
しかし、私は普段Emacsを使用しているのです。
Emacsでも同じようなことがしたいと思い、ネットの情報を参考にさせていただきながらスクリプトを作りました。本当はEmacsLispで作ろうと思ったのですが、
妥協してRubyで実装しちゃいました。以下その紹介です。
ソース
https://github.com/ckona/gh_operation
使い方
READMEに書きましたが改めて説明を。
Githubでファイルを開く
$ ruby open_file_on_gh.rb <file_path> <line_number>
open_file_on_gh.rb
- 第一引数: Githubで開きたいファイルのパス
- 第二引数: 行番号
これで、Githubでファイルが開けます。
GithubでPRを開く
$ ruby open_pr_on_gh.rb <file_path> <line_number>
open_file_on_gh.rb
- 第一引数: 対象のファイルパス
- 第二引数: 行番号
これで、対象ファイルの該当行を変更した直近のPRが開けます。
Emacs側の設定
上記のスクリプトを任意の場所に置いて、それを呼ぶだけです。
私の場合、Git系はhydraでM-gに設定してあるので、
M-g oでファイルをGithubで開く、
M-g PでPRを開く、
というようにしています。(defun open-file-on-github () (interactive) (shell-command (concat "ruby ~/projects/gh_operation/open_file_on_gh.rb " buffer-file-name " " (number-to-string (line-number-at-pos))))) (defun open-pr-on-github () (interactive) (shell-command (concat "ruby ~/projects/gh_operation/open_pr_on_gh.rb " buffer-file-name " " (number-to-string (line-number-at-pos)))))コードの大まかな内容
open_file_on_gh.rb
- 対象ファイルがあるディレクトリを取得し、そのディレクトリに移動する
- そこで
git remote get-url originコマンドを実行し、Githubのアカウント名、リポジトリ名を取得する- 対象ファイルのrootディレクトリ(Railsでいうと
Rails.root)を取得し、pathを作成する- 作成したパスを
hubコマンドで叩く!open_pr_on_gh.rb
- 対象ファイルがあるディレクトリを取得し、そのディレクトリに移動する
- そこで
git remote get-url originコマンドを実行し、Githubのアカウント名、リポジトリ名を取得するgit blameコマンドを駆使し、コミットハッシュを取得するgit logコマンドとコミットハッシュを駆使し、PRの番号を取得する- Githubアカウント名、リポジトリ名、PR番号を元にURLを作成
- そのURLを
hubコマンドで叩く!注意点
Rubyがインストールされていることが必須hubコマンドがインストールされていることが必須- 行番号の指定によっては開かない。。
httpsプロトコルだと動かないナドナド
あとがき
時間あるときに、
git blameで何をしているのか等、コードの詳細の追記をしたいと思います。
ちなみに、このスクリプトを呼ぶだけでなので、Vimでも使用できると思います。参考
- 投稿日:2019-07-24T00:28:34+09:00
Githubでファイルを開く、該当行のPullRequestを開くRubyスクリプトを作った
背景
業務で下記のようなことをしたい!、というような場面ってありませんか?
- 今エディタで開いているファイルをGithub上で開きたい
- 今エディタで見ている行を変更したPullRequest(以下PR)を確認したい
- PRを確認しないと、なぜそういう変更になったのか等の背景が分からないですよね
- PRが分かれば、だいたい元issueにもたどり着けますよね
VSCodeだと簡単にGithubに飛べますよね。
しかし、私は普段Emacsを使用しているのです。
Emacsでも同じようなことがしたいと思い、ネットの情報を参考にさせていただきながらスクリプトを作りました。本当はEmacsLispで作ろうと思ったのですが、
妥協してRubyで実装しちゃいました。以下その紹介です。
ソース
https://github.com/ckona/gh_operation
使い方
READMEに書きましたが改めて説明を。
Githubでファイルを開く
$ ruby open_file_on_gh.rb <file_path> <line_number>
open_file_on_gh.rb
- 第一引数: Githubで開きたいファイルのパス
- 第二引数: 行番号
これで、Githubでファイルが開けます。
GithubでPRを開く
$ ruby open_pr_on_gh.rb <file_path> <line_number>
open_file_on_gh.rb
- 第一引数: 対象のファイルパス
- 第二引数: 行番号
これで、対象ファイルの該当行を変更した直近のPRが開けます。
Emacs側の設定
上記のスクリプトを任意の場所に置いて、それを呼ぶだけです。
私の場合、Git系はhydraでM-gに設定してあるので、
M-g oでファイルをGithubで開く、
M-g PでPRを開く、
というようにしています。(defun open-file-on-github () (interactive) (shell-command (concat "ruby ~/projects/gh_operation/open_file_on_gh.rb " buffer-file-name " " (number-to-string (line-number-at-pos))))) (defun open-pr-on-github () (interactive) (shell-command (concat "ruby ~/projects/gh_operation/open_pr_on_gh.rb " buffer-file-name " " (number-to-string (line-number-at-pos)))))コードの大まかな内容
open_file_on_gh.rb
- 対象ファイルがあるディレクトリを取得し、そのディレクトリに移動する
- そこで
git remote get-url originコマンドを実行し、Githubのアカウント名、リポジトリ名を取得する- 対象ファイルのrootディレクトリ(Railsでいうと
Rails.root)を取得し、pathを作成する- 作成したパスを
hubコマンドで叩く!open_pr_on_gh.rb
- 対象ファイルがあるディレクトリを取得し、そのディレクトリに移動する
- そこで
git remote get-url originコマンドを実行し、Githubのアカウント名、リポジトリ名を取得するgit blameコマンドを駆使し、コミットハッシュを取得するgit logコマンドとコミットハッシュを駆使し、PRの番号を取得する- Githubアカウント名、リポジトリ名、PR番号を元にURLを作成
- そのURLを
hubコマンドで叩く!注意点
Rubyがインストールされていることが必須hubコマンドがインストールされていることが必須- 行番号の指定によっては開かない。。
httpsプロトコルだと動かないナドナド
あとがき
時間あるときに、
git blameで何をしているのか等、コードの詳細の追記をしたいと思います。
ちなみに、このスクリプトを呼ぶだけでなので、Vimでも使用できると思います。参考

