日記帳

プログラミングのことをつぶやく日記です。

rbenv-each を用いて、 rbenv で管理している Ruby のすべてのバージョンに対して、コマンドを実行する

なぜ行ったのか

RubyGems脆弱性があるので、rbenv-eachを導入して、まとめてコマンドを実行してみた。

週刊Railsウォッチ(20190311-1/2前編)「Rails Conductor」14年ぶり復活なるか?、RubyGemsに複数の脆弱性、2009年のRailsエコシステムほか

リポジトリ

rbenv/rbenv-each: rbenv plugin to Run a command across all installed rubies.

インストール方法

公式リポジトリより

$ git clone https://github.com/rbenv/rbenv-each.git "$(rbenv root)"/plugins/rbenv-each

# インストール確認

$ rbenv help each
Usage: rbenv each [-v] <command> [arg1 arg2...]

Executes a command for each Ruby version by setting RBENV_VERSION.
Failures are collected and reported at the end.

   -v  Verbose mode. Prints a header for each ruby.

動作確認

このコードを参考に、Rubyのすべてのバージョンで、そのバージョン情報を出力する。

Rubyのバージョンを出力する。 - こせきの技術日記

$ rbenv each ruby -e 'puts "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}]"'
ruby 2.2.8 (2017-09-14 patchlevel 477) [x86_64-darwin16]
ruby 2.5.1 (2018-03-29 patchlevel 57) [x86_64-darwin16]

いざアップデート

脆弱性の修正パッチが当たっているのがRuby2.4以降らしいので、それより前は失敗する。この場合は 2.2.8 のupdateは失敗することに。

$ rbenv each gem update --system
Updating rubygems-update
Fetching: rubygems-update-3.0.3.gem (100%)
ERROR:  Error installing rubygems-update:
        rubygems-update requires Ruby version >= 2.3.0.
ERROR:  While executing gem ... (NoMethodError)
    undefined method `version' for nil:NilClass
Updating rubygems-update
Fetching rubygems-update-3.0.3.gem
Successfully installed rubygems-update-3.0.3
Parsing documentation for rubygems-update-3.0.3
Installing ri documentation for rubygems-update-3.0.3
Installing darkfish documentation for rubygems-update-3.0.3
Done installing documentation for rubygems-update after 40 seconds
Parsing documentation for rubygems-update-3.0.3
Done installing documentation for rubygems-update after 0 seconds
Installing RubyGems 3.0.3
Bundler 1.17.3 installed
RubyGems 3.0.3 installed
Regenerating binstubs
Parsing documentation for rubygems-3.0.3
Installing ri documentation for rubygems-3.0.3

=== 3.0.2 / 2019-01-01

Minor enhancements:

* Use Bundler-1.17.3. Pull request #2556 by SHIBATA Hiroshi.
* Fix document flag description. Pull request #2555 by Luis Sagastume.

Bug fixes:

* Fix tests when ruby --program-suffix is used without rubygems
  --format-executable. Pull request #2549 by Jeremy Evans.
* Fix Gem::Requirement equality comparison when ~> operator is used. Pull
  request #2554 by Grey Baker.
* Unset SOURCE_DATE_EPOCH in the test cases. Pull request #2558 by Sorah
  Fukumori.
* Restore SOURCE_DATE_EPOCH. Pull request #2560 by SHIBATA Hiroshi.

=== 3.0.1 / 2018-12-23

Bug fixes:

* Ensure globbed files paths are expanded. Pull request #2536 by Tony Ta.
* Dup the Dir.home string before passing it on. Pull request #2545 by
  Charles Oliver Nutter.
* Added permissions to installed files for non-owners. Pull request #2546
  by SHIBATA Hiroshi.
* Restore release task without hoe. Pull request #2547 by SHIBATA Hiroshi.


------------------------------------------------------------------------------

RubyGems installed the following executables:
        /Users/yamakawa00/.anyenv/envs/rbenv/versions/2.5.1/bin/gem
        /Users/yamakawa00/.anyenv/envs/rbenv/versions/2.5.1/bin/bundle

Ruby Interactive (ri) documentation was installed. ri is kind of like man
pages for Ruby libraries. You may access it like this:
  ri Classname
  ri Classname.class_method
  ri Classname#instance_method
If you do not wish to install this documentation in the future, use the
--no-document flag, or set it as the default in your ~/.gemrc file. See
'gem help env' for details.

RubyGems system software updated
FAILED IN: 2.2.8

結果として、2.5.1しか脆弱性修正対象のバージョンがなかったので、rbenv-eachを導入する必要がなかったのではと思ったが、何事も経験なので。

Gitで管理しているプロジェクトで別のブランチから1ファイルだけ持ってくる

rebaseミスって、masterブランチから対象ファイルを持ってきたい時があるのでメモ

# まずはファイルが該当ブランチに存在するか確認する
git show <コピー元ブランチ名>:<ファイル名>
# 存在したら、今いるブランチへ適応させる
git checkout <コピー元ブランチ名> -- <ファイル名>

実際に使う時

git show master:hoge.rb
git checkout master -- hoge.rb

これ、実はhelpに書いてある。ちゃんとhelp読もうね。(戒め)

$ git show -h
usage: git log [<options>] [<revision-range>] [[--] <path>...]
   or: git show [<options>] <object>...

$ git checkout -h
usage: git checkout [<options>] <branch>
   or: git checkout [<options>] [<branch>] -- <file>...

git-update を導入した

sue445.hatenablog.com

この記事をみて git-update コマンドを置いたら便利そうだなーと思って導入した。 git-update コマンドは、作業中のブランチをmasterブランチの先端に向ける認識。 よく何をどこにしまったか忘れるのでmemo.

環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G1408

$ git --version
git version 2.19.0

導入ログ

cd /usr/local/bin # PATHが通っているので、ここにコマンドをおくぞ
vi git-update # 記事のソースをぺたり
chmod a+x git-update # 権限を全てのユーザー実行可能へ
git-update

/usr/local/binエイリアス張って、リポジトリ管理しろよって感じだが、自作コマンドが全くないので今はこの運用。管理する必要が出てきたらリポジトリで管理する。最初から気合を入れてはいけない。

GMOあおぞら銀行の残高を自動取得するスクリプトを組んだ

課題

給与受け取り口座がGMOあおぞら銀行に変更になった。マネーフォワードが対応してなくて、残高確認のために、毎回GMOあおぞら銀行のページを徘徊するのは煩わしい。自動化して毎日チェックできないものか。

解決策

もっとも理想的なのはマネーフォワードがGMOあおぞら銀行に対応することである。しかし実装予定の予告も出ていないので、神に祈るしかない。無神論者は神に祈る習慣はないので自分でなんとかすることにする。

労力が少なく具体的な解決策を一つあげるとすれば、スクリプトを書いてcronで毎日流して通知する形がいいのではないか。なのでPuppeteerの練習も兼ねてNode.jsでやってみる。

「Puppeteer入門 スクレイピング+Web操作自動処理プログラミング」を購入して、少し練習して挑戦してみた。

Puppeteer入門 スクレイピング+Web操作自動処理プログラミング

Puppeteer入門 スクレイピング+Web操作自動処理プログラミング

具体的な解決策として Puppeteer を用いて自動ログインしてみる

最初に完成したコードを記載しておく。

Puppeteer_practice/aozora_login.js at master · ryuchan00/Puppeteer_practice

まずはPuppeteerのインストールから始める。

npm install puppeteer

次はPuppeteerの読み込みをする。

const puppeteer = require('puppeteer');

ユーザーIDとパスワードの取り扱い

迷ったのが、ユーザーIDとパスワードをどこから取得するかだ。思いつくだけでも以下の場所から取得できそうだ。

この中で選択するのであれば、ソースコードを公開する時に安全で環境によって値を変更できる「環境変数」で保持した方が良さそうだ。dotenvというライブラリを使えば.envファイルに書いたものを環境変数として扱ってくれるらしい。

qiita.com

### dotenvのインストール
npm install dotenv

dotenvの読み込み

require('dotenv').config();

const USER_ID = process.env.AOZORA_USER_ID;
const PASSWORD = process.env.AOZORA_PASSWORD;

.envファイルの中身

AOZORA_USER_ID="aaaaa"
AOZORA_PASSWORD="bbbbb'

環境変数AOZORA_USER_IDにはユーザーIDを、AOZORA_PASSWORDにはパスワードを入れる。

GMOあおぞら銀行のページまで自動で遷移する

すでにユーザーIDとパスワードを用意してしまったが、まずは自動でGMOあおぞら銀行のログインページまで遷移してみることにする。最初の歩幅を縮めて一つ一つ確認していこう。初めて使うツールならなおさらだ。ログインページまで自動でたどり着くには、ブラウザの新しいページを開いて、gotoメソッドで遷移先のURLを引数として与えてあげる。node aozora_login.jsで実際に実行して確認していく。ログインページが開ければOKだ。

(async() => {
// Puppeteerの起動
    const browser = await puppeteer.launch({
        headless: false,
        slowMo: 50,
    });

    // 新しいからのページを開く
    const page = await browser.newPage();

    // view portの設定
    await page.setViewport({
        width: 1200,
        height: 800,
    });

    // GMOあおぞら銀行のログインページまで移動する
    await page.goto('https://sso.gmo-aozora.com/b2c/login');
})();

自動ログインしてみる

ログインするためにはユーザーIDとパスワードをフォームに入力する。こうやって日本語で書いたら何を当たり前なこと的なことを書いているが、実際にコードで表現すると以下のようになる。typeメソッドで各フォームに入力していく。要素はユーザーIDはname="username"、パスワードはname="password"を指定する。(余談だが、もしPOSTメソッドにて実行するのであれば、トークンが必要なのだった。)ログインボタンをクリックするためにはclickメソッドを使用する。これで会員トップページまでたどり着ける。

    // ユーザーIDを入力する
    await page.type('input[name="username"]', USER_ID);
    // パスワードを入力する
    await page.type('input[name="password"]', PASSWORD);

    // ログインボタンをクリックする
    await page.click('button[type="submit"]');

会員ページトップの残高情報を取得してみる

残高の情報をコンソールに表示できるようにしてみる。まず残高の情報が表示されるまで、スクリプトを中断させる必要がある。waitForメソッドを用いて6秒待つことにする。それ以下だと先にスクリプトが残高の要素を取得しようとして失敗することがある。残高の要素はamountクラスのspanタグの要素である。evaluateメソッドを使用して、定数amountに残高の数値を代入する。これでCUIで残高を表示することができた。最後にブラウザを終了するようにすれば完璧だ。

    await page.waitFor(6000);

    // 要素の取得
    const amount = await page.evaluate((selector) => {
        // evaluate関数に渡す第一引数のfunctionは、
        // 第二引数として渡したパラメータをselectorに引き継いでブラウザ内で実行する
        return document.querySelector(selector).textContent;

    }, 'span.amount span');

    console.log('残高:' + amount);

    // ブラウザの終了
    await browser.close();

これから

これをChrome extensionに移植してマネーフォワードのページを開いた時にGMOあおぞら銀行の情報も追加してあげたい。できるだろうか。年末にやってみる。

電気通信大学 先端工学基礎課程 に合格した

先日、電気通信大学 先端工学基礎課程 AO入試に合格しました。来年4月より大学1年生です。

約5ヶ月前に受験を決めて、運よく合格することができました。応援してくださった皆様、本当にありがとうございました。

leokun0210.hatenablog.com

もし社会人で受験したいけど情報が欲しいという方がいたら、よければ参考にしてください。ただし記事の内容が来年以降も当てはまらない可能性もあるのであくまで参考情報の一つとしてお考えください。

動機

上記の受験を決意をするときのエントリーを言及した「自分のキャリアに幅を持たせる」側面が強いです。面接の時にもお話ししたのですが、IT業界はIPAの調査によれば人材の質・量共に不足気味です。(この辺の根拠はIT人材白書2018を見てね)そうなると他の業界から優秀な人材が多く人が流れてきます。今の自分のように大学の専攻はコンピューターサイエンス(以下CS)以外に人も今以上に多くなってくるでしょう。そうなると1つのポジションの競争率が高くなります。業務に関してほぼ同等の能力を有する場合は、理数系の知識に基づいたロジカルな論理的思考力のバックグラウンドを持つ人材、つまりはCSの知識の方が有利ではないかという推測して入学を決意しました。面接でもこれを掘り下げたことを言いました。

試験の内容

1日目は、数学・物理化学・英語の3教科合わせて120分の総合問題を解きました。

2日目は、今まで数学・物理を学んだかのアンケートと数学Ⅱまでのテスト、あとは志望動機などを聞くための集団面接と個人面接がありました。

やったこと

総合問題対策

5ヶ月という期間でフルタイムで働きながら4教科を勉強するのは時間が足りないです。ネットでは、社会人は総合問題の点数はそこまで重視されないとの書き込みを見つけたので、数学と英語に絞って勉強しました。物理化学は余裕があったらやるぐらいの気持ちでした。

英語

上記の教材を1週しました。実際の出来は半分以上は確実に取れたかなという印象でした。

数学

  • 白チャート数ⅠA
  • 白チャート数ⅡB
  • 白チャート数Ⅲ

微分積分三角関数、行列を中心にやりました。過去問で出題されない範囲の傾向がわかるので、過去3年間で一問も出題されていない単元は手をつけませんでした。総合問題の出来は正直あんまりできませんでした。ただ、2日目の数学のテストは7割ぐらいはできたと思っています。

物理化学

  • チャート式物理基礎
  • チャート式化学基礎

これらを少しだけやっただけでした。正直勉強時間がなかったので、ほぼ捨て科目でした。

集団面接で総合問題の出来について聞かれるのですが、社会人の得点はそこまで高くない印象でした。6人と一緒に面談したのですが、勉強期間が1ヶ月未満の人もいました。ただなぜ得点が低いのか、入学後のフォローはどうするかを聞かれます。

面接対策

社会人は面接の比重の方が大きいと思ったので、面接の根幹になるであろう志望動機は3~4日かけて作成しました。志望動機は、「なぜ大学を志望したのか」「なぜ電気通信大学なのか」「なぜ先端工学基礎課程なのか」の3つを一本の繋がる線にして書きました。規定文字数が800文字程度でしたが、草案は1400文字ほど書いてそれから削る作業をしました。特に苦労した箇所が「なぜ電気通信大学か」でした。これは電気通信大学はどのような人材を輩出する目的があり、他の大学とどのように違うのかを調査して書きました。パンフレットは何回も読み返した記憶があります。

推薦書は会社の方に書いていただきました。本当にありがとうございました。

実際は集団面接では、志望動機、総合問題の感想などが聞かれました。個人面接では、集団面接の掘り下げと共に勤務状況や通学距離などが聞かれます。ちなみに1日目はいたのに2日目の面接に来ない人が数人いました。

試験の時に注意した方がいいところ

数学は最低でも数Ⅱまでは力を入れておく

試験2日目は、面接のみだと思っていましたが、数Ⅱまでの基礎的な問題を1時間解きました。おそらく社会人受験者の評価資料に使うのではと思いました。社会人受験者は、高校卒業から時間が経過しており、総合問題を解答するには厳しい人もいるので、別途基礎学力の調査が必要なのかなと思いました。

2日目の面接は、集団面接から個人面接まで2~4時間ぐらい待たされる

集団面接は午前中に終わるのですが、個人面接になると、人数が60人前後おり、一人当たり10分以上面接するので、かなり待たされます。自分は4時間ぐらい待ちました。待ち教室は結構寒いので防寒対策はしっかりした方がいいでしょう。

面接では機転が効くかの質問もされる

集団面接で、「日本の文化を一つあげて、どうのように外国人に説明しますか」と聞かれました。結構不意打ち気味だったので焦りました。答えるのに難儀している受験者もいました。受験前は新聞の1面に軽く目を通すぐらいはした方がいいかなと思いました。

何を実社会に活用できるか

大学に行く目的は情報理工系の知識の専門性を高めることです。1~2年生の間は数学や物理の基礎を学んで出来ることを増やすフェイズ、3~4年生は専門性をグッと引き上げるフェイズと分けて捉えています。専門性を高めて、会社の人材層を厚くするのが自分の役割だと考えています。やや抽象的な表現にしたのは、まだ実際に講義を受けるのは未来の話なため、どの技術領域の専門性を引き上げるかの明言が難しいためです。ただこういうスタンスで会社に貢献するつもりは変わりありません。