投稿者「sasaki」のアーカイブ

[Ruby] cycleメソッド(Array)の使い方

概要

RubyのArray#cycleメソッドは、配列内の要素を一定回数、あるいは無限に循環し、指定したブロックを実行するためのメソッド。例えば[1,2,3]の配列に対してcycleメソッドを用いると、1,2,3,1,2,3,1,2,3,1,2,3…と、配列の要素を循環して処理を行うことができる。

riによるドキュメント

$ ri Array#cycle
= Array#cycle

(from ruby core)
------------------------------------------------------------------------------
  ary.cycle(n=nil) { |obj| block }  -> nil
  ary.cycle(n=nil)                  -> Enumerator

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

Calls the given block for each element n times or forever if nil is given.

Does nothing if a non-positive number is given or the array is empty.

Returns nil if the loop has finished without getting interrupted.

If no block is given, an Enumerator is returned instead.

  a = ["a", "b", "c"]
  a.cycle { |x| puts x }     # print, a, b, c, a, b, c,.. forever.
  a.cycle(2) { |x| puts x }  # print, a, b, c, a, b, c.

循環回数を指定する場合

cycleメソッドの引数で指定した回数、配列を巡回しながらブロックを実行する。戻り値は必ずnilになる。

irb(main):001:0> [1,2,3].cycle(3) {|n| p n }
1
2
3
1
2
3
1
2
3
=> nil

循環回数を指定しない場合

cycleメソッドの引数を指定しない、あるいはnilを明示的に指定した場合、配列を無限に巡回する。
当然無限ループになるので、sleepを挟んで出力すると、1秒ごとに1要素、永遠に出力し続ける。

irb(main):002:0* [1,2,3].cycle {|n| p n; sleep 1}
1
2
3
1
2
3
1
2
3
(以下省略)

0以下を指定した場合

cycleメソッドの引数に0以下を指定した場合、ブロックは一度も呼び出されない。

irb(main):013:0* [1,2,3].cycle(0) {|n| p n }
=> nil
irb(main):014:0> [1,2,3].cycle(-1) {|n| p n }
=> nil

ブロックを指定しない場合

cycleメソッドのブロックを指定しない場合、cycleメソッドはEnumeratorオブジェクトを戻すので遅延評価できる。

irb(main):028:0* enum = [1,2,3].cycle
=> #<Enumerator: [1, 2, 3]:cycle>
irb(main):029:0> enum.first(10)
=> [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]

[Rails] ActiveAdminにCommentモデルをregisterできない

概要

Railsの管理画面作成用gemであるActiveAdminを用いて、ユーザのコメントなどを扱うCommentモデルを管理画面で読み書きできるようにしようとした際のトラブルと、その解決策の備忘録。

問題点

以下コードで、CommentモデルをActiveAdminにregisterした。

ActiveAdmin.register Comment do
end

以下のエラーが出た。

ActiveAdmin::ResourceCollection::ConfigMismatch
You’re trying to register ActiveAdmin::Comment as Comment, but the existing ActiveAdmin::Resource config was built for Comment!

あれ、もうCommentモデルは管理画面に追加済みだったかな‥‥?
誰かが先に対応したのかな‥‥?

と試行錯誤してたがそういうわけじゃないみたい。

解決策

どうやらActiveAdmin側にも、管理者のコメントを扱うためのCommentモデルが存在し、名前が競合してしまったのが原因らしい。

解決策として、ActiveAdminの設定ファイルにて、ActiveAdmin側のCommentモデルの名前を差し替える手段があるので、ActiveCommentに差し替える。

config/initializers/active_admin.rb

# CommentモデルとActiveAdminのCommentモデルが競合するので、
# ActiveAdmin側を明示的にAdminCommentに変更する
config.comments_registration_name = 'AdminComment'

3年目プログラマが参考にしたQiita記事まとめ⑦

概要

特にカテゴリもレベルも偏らずにざっくばらんに、参考になったQiita記事を一言添えて列挙するシリーズ7本目

Qiitaまとめシリーズ

PHPのjson_decodeがNULLになる

稀によくある。言語間のデータの受け渡しに使うJSONで、言語依存な問題があると辛い。こういうこともあるんだよと覚えておくといざという時に役立ちそう。

iTerm2の設定をいじってターミナル作業を効率化する

シングルモニタで作業する際はこの方法採用した。物凄く捗る。それまでは「開発はマルチモニタないとやってらんないよ」という感じだったが、この手法を取り入れてから捗る捗る。作業の内容次第ではマルチモニタを使ってたときよりもサクサクできるレベル。

Pythonにswitch文無いんですか!?

switch文使う派と使わない派の間を高速掌返しし続けて長い年月が経過したけど、言語機能としてswitchが無いと不便にも感じる。オブジェクト指向でswitchが欲しくなったらそれはポリモーフィックな改善余地があると思うけど。

コマンドを間違えるたびに美少女に罵られたい!

シェルスクリプトでcommand not found をフックできるの初めて知った。Linuxでなくシェルの機能だからbash依存かもしれないけど。他にもフックできるイベントがあるのかな。その辺り調べると開発が捗る可能性がある。ちょっと調べてみようか。

ブックマークレットの登録方法

ブックマークレートって概念を初めて知った。なるほど、ブックマークから頻繁に開くページで、かつ特定の処理を行いたい時はありかな。チャットワークとTwitterとBacklogとSlackぐらいだけど何か使いみちないかなぁ。

cd したら ls する

cdしたら無意識にlsタイプする癖が染み付いてしまったのでcd後のlsを自動化するスクリプトを採用。かなり捗ってる。これは便利。lsが自動でかかるのが邪魔なときも稀にあるけど、頻度的には無視できる問題。

フロントエンドチェックリスト(日本語訳)

これは良い!見落としがちな問題から全然知らないことまで載ってる。フロントエンドエンジニアになるにはこういうとこ抑えなきゃならないから後でじっくり1個ずつ調べてく。

プログラミングの階段を登る方法をまとめた

なんかいつもオブジェクト指向って立ちはだかる壁になってんな。

文法を知っているだけのレベルで現場に入るとStruts全盛期のいわゆる「Action職人」のように、アプリケーションの決められた箇所に業務処理を手続き型で実装するスキルセットしか持つことができなくなります。この状態では自分の実装箇所以外の処理内容は知らないし、理解することもままなりません。
なお、この労働集約的な手法一辺倒で作られたソフトウェア(労働集約パターンと名付ける)は、機能追加や障害対応に非常に脆いです。さらに良くないのはそういう環境で育つとそれを当たり前と感じ、それ以上のプログラミング学習をやめる一因となることです。学習をやめてしまったら、その人は自分の知っている労働集約パターンでしかプログラミングができないだけでなく、それを押し付けてしまうダークサイドに入ることでしょう。

この辺が日本の(?)プログラマにありがちな気がする。SESによる多階層な業務分割が原因?そうはなりたくないなぁ。

複数人での Git 開発に便利な 3 つのコマンド

git blameは初めて知ったけどこれは便利。「犯人探し」って言い方はアレだけど、実際にそれらしい場面に遭遇してすぐに役立った。

今風なデザインに変えるためにできそうなこと

こう見ると、Twitter、Facebookあたりが先導したUIがどんどん流行っていくというか模倣されてきてるのかな。単純にユーザ数が膨大で、かつ多くの時間をかけて利用してるから、ユーザがそのUIにすぐ馴染むんだろうなぁ。

[Vue + OnsenUI] v-ons-navigatorでページ遷移する

概要

Vue2.4.4及びOnsenUIのVue2向けモジュールであるvue-onsenui2.2.1のv-ons-navigatorを用いた画面遷移を実装を行う。サンプルは以下のgifの通り。

※ 撮影の都合でgifがカクついてますが、実際はもっとヌルヌル切り替わります

前提

以下の環境で動作確認済み

debian 9.2
vue 2.4.4
vue-onsenui 2.2.1

ナビゲーション用コンポーネントの実装

まずは、v-ons-navigatorを用いたナビゲーション画面全体を制御するコンポーネントを作成する。

<template>
  <v-ons-navigator swipeable :page-stack="pageStack" @push-page="pageStack.push($event)">
  </v-ons-navigator>
</template>

<script>
  import test1 from './test1'
  export default {
    data() {
      return {
        pageStack: [test1]
      }
    }
  }
</script>

v-ons-navigatorのpage-stack属性には、名の通り積み上げているページのコンポーネントをバインドする。
例えばトップ画面を開いている時は[トップ画面],トップ画面から設定画面に遷移した状態であれば[トップ画面,設定画面]と配列に積まれた状態になるようにする。

今回は、test1ページを最初に表示しておきたいので

data() {
  return {
    pageStack: [test1]
  }
}

のように、test1を初期値として積んでおく。

@push-page="pageStack.push($event)"

ページを積む処理はイベントで定義して置いて、これを表示中の子コンポーネントから呼び出すことで画面遷移を実現する。

1ページ目を作成

<template>
  <v-ons-page>
    <v-ons-toolbar>
      <div class="center">test1</div>
    </v-ons-toolbar>
    <div>テストページ1</div>
    <v-ons-button @click="push">テストページ2へ</v-ons-button>
  </v-ons-page>
</template>

<script>
  import test2 from './test2.vue'
  export default {
    methods: {
      push() {
        this.$emit('push-page', test2)
      }
    }
  }
</script>

1ページめには、2枚目のページへの移動手段を用意する。移動するためのボタンがクリックされた際に、以下のように親コンポーネントのpush-pageイベントを発火し、2ページ目であるtest2をスタックに追加する。そうすることで、画面は自動的にスタックの先頭であるtest2を表示するようになる。

this.$emit('push-page', test2)

2ページ目の実装

<template>
  <v-ons-page>
    <v-ons-toolbar>
      <div class="left">
        <v-ons-back-button>戻る</v-ons-back-button>
      </div>
      <div class="center">test2</div>
    </v-ons-toolbar>
    <div>テストページ2</div>
  </v-ons-page>
</template>

<script>
</script>

2ページ目には、1ページ目に戻るための仕組みを実装する。といっても、手動でStackからページを取り除く必要はなく、上記コードのようにv-ons-back-button
を設置することでその辺りを自動でやってくれる。v-ons-back-button以外をトリガに戻りたい場合はスタックを直接弄る必要がありそう。

3年目プログラマが参考にしたQiita記事まとめ⑥

概要

特にカテゴリもレベルも偏らずにざっくばらんに、参考になったQiita記事を一言添えて列挙するシリーズ6本目

Qiitaまとめシリーズ

Vue.jsのpropsカスタムバリデーターを使った堅牢なコンポーネント作成

Vueに限らずReactもだけど、こういうのちゃんと使わないといけないなと思った。ユーザ向けのバリデーションだけじゃなくてプログラマ向けのバリデーションもしっかりすることで長い目で見た時に開発効率が大きくあがるはず。例えば思ってたのと違う属性を与えられて変な挙動して、その原因を調べる時にコードを追うよりもバリデーションエラーの通知がスッと出てきたほうが楽なハズ。

○○を含む?/○○で始まる?/○○で終わる?

PHPの話だけど、多言語でも言えること。題のような目的を果たす時に何でもかんでも正規表現を使うのは辞めよう。正規表現は基本的に計算コストが高いので、コストが気にならない、可読性を高めたい場合に限るようにしよう。

属人化を避ける

属人化とは「○○さんがいないとプロジェクトが進まない!」という状況。属人化を避けるということは、誰かが突然居なくなってもプロジェクトを進められるようにすること。無理難題にも見えるが、きっちり日頃から突然居なくなる準備をしておけば案外大丈夫だったり。

たった1人から始める社内テストコード文化

テストの文化が無いのなら一人で始めればいいじゃないか。なお話。この手の記事にしては珍しくデメリットや、結局うまく行かなかったことについても経験から書かれているので参考になる。

Vue.jsのライフサイクルメモ

ライフサイクルってVueでもReactでもAngularでも、何ならネイティブアプリでも概ね同じようなワードと挙動の組み合わせになってるのかな。個別に憶えるのしんどいな。

ツリーマップでタスクの規模を可視化するタスク管理ツールを作ってみた

UIめっちゃかっこいい・・・。短期的でリアルタイム性のあるタスク管理だと強力そう。長期的な話になってくると色々と機能不足なので、使い分けられると良いかな。Backlogみたいには使えないけど、Trelloみたいには使える感じ。

なんちゃってスクラム開発

「アジャイルやってます」「スクラムやってます」「XPやってます」「DDLやってます」←だいたいやってない

「エンジニアの転職メモ」の内容を実践した結果

多分以前紹介したエンジニアの転職メモを実践した人の報告。やっぱり実際に行動した人の結果を知れるとわかりやすい。ちなみに私も実践して1ヶ月ほどで複数社からご連絡頂きました。確かな効果はあるみたい。

プロダクトに日本語の全文検索機能を加えたい、検索インデックスのリアルタイム更新もほしい というときの手軽な方法

全文検索?like and like and like!!はもう辞めたい。 mySQLの機能をしっかり活用すると意外とすんなり実装できる模様。まぁモダンな開発するのであればElasticsearchの導入とか本格的に検討するのも一手。

Qiita の「最終更新日から1年以上が経過しています。」を強化する

あんまり気にしてなかったけど、Qiitaみたいに情報の鮮度が重要なサイトでこういった機能って重要だなと思った。自分が投稿した記事も、そろそろこの警告が出てるのがチラホラあるので確認したい。といっても確認した結果まだ問題なかった場合どうしたら良いんだろ。更新する必要はないけど更新しないと警告消えないし‥‥。
◯年◯月時点で再現できましたとか、最新版でも問題ないですとか書いたほうが親切なのかな。

[Vue + OnsenUI] v-ons-tabbarで描画するVueコンポーネントを切り替える

概要

Vue2.4.4及びOnsenUIのVue2向けモジュールであるvue-onsenui2.2.1を用いて、タブによる画面の切り替えの実装に関する備忘録。本記事では、以下のようにタブを切り替えることで描画するVueコンポーネントを切り替える。

※ 撮影の都合でgifがカクついてますが、実際はもっとヌルヌル切り替わります

前提

以下の環境で動作確認済み

debian 9.2
vue 2.4.4
vue-onsenui 2.2.1

各タブに表示するコンポーネントを実装

本記事では、gifの通り「コンポーネント1」「コンポーネント2」「コンポーネント3」の3種類のコンポーネントをタブで切り替える。

まずは、その3種類のコンポーネントを作成する。といってもテキストを描画するだけの適当なもの。

component1.vue

<template>
  <v-ons-page>
    コンポーネント1
  </v-ons-page>
</template>

component2.vue

<template>
  <v-ons-page>
    コンポーネント2
  </v-ons-page>
</template>

component3.vue

<template>
  <v-ons-page>
    コンポーネント3
  </v-ons-page>
</template>

タブの実装

v-ons-tabbarを用いてタブを描画する

<template>
  <v-ons-page>

    <v-ons-tabbar position="auto" :visible="true" :tabs="tabs" :index.sync="tabIndex">
    </v-ons-tabbar>

  </v-ons-page>
</template>

上記templateに対して、tabIndexとtabsを定義する。tabsでは、各タブに表示するアイコンと、表示用ラベル、そしてタブがアクティブになった時に描画するコンポーネントを定義する。各タブに対して、前項で作成したコンポーネントをimportして適用する。

import component1 from './component1'
import component2 from './component2'
import component3 from './component3'

export default {
  name: 'index',
  data() {
    return {
      tabIndex: 0,
      tabs: [
        {
          icon: 'fa-home',
          label: '1',
          page: component1,
        },
        {
          icon: 'fa-user',
          label: '2',
          page: component2,
        },
        {
          icon: 'fa-cog',
          label: '3',
          page: component3,
        }
      ]
    }
  },
  methods: {
  },
  components: { component1, component2, component3 },
}

[Rails] ActiveAdminで新規作成(編集)フォームをカスタマイズする

概要

Ruby on rails(5.0.3)用のgemライブラリであるActiveAdminを用いて管理画面を実装する際の、新規登録フォーム、あるいは編集フォームをカスタマイズする方法を確認する。本記事は公式ドキュメントの内容をベースに、カスタマイズ結果の画像を載せつつ確認する。

※ Ruby on rails及びActive Admin全般の説明は行っていませんのでご注意ください

前提

以下の環境で動作確認済み

debian 8.6
ruby 2.3.1
ruby on rails 5.0.3
active admin 1.0.0

使用するモデル

本記事では、以下のシンプルなモデルをベースにする。以下のItemモデルは、商品データベースを想定したもので、商品名、カテゴリ、品数、販売フラグ、商品説明を持つ。なお、本来であればカテゴリはCategoryモデルを参照するなどの設計になるが、ここでは簡略化のために直接文字列を入れるようにする。

$ rails generate model Item name:string category:string num:integer is_sale:boolean description:text
class CreateItems < ActiveRecord::Migration[5.0]
  def change
    create_table :items do |t|
      t.string :name
      t.string :category
      t.integer :num
      t.boolean :is_sale
      t.text :description

      t.timestamps
    end
  end
end

デフォルトフォーム

formメソッドを記述しなくともモデルの内容に応じてフォームは自動生成されるが、あえてコードを書くなら以下のようになる。

ActiveAdmin.register Item do

  # 編集を許可するフィールドを定義
  permit_params :name, :category, :num, :is_sale, :description

  form do |f|
    f.semantic_errors # エラーメッセージ表示
    f.inputs          # 入力フィールドを表示
    f.actions         # submit/cancelボタンを表示
  end

end

編集できる列を制限

例えば商品数や販売フラグを編集できないようにする場合は以下のように、inputsメソッドにブロックを渡して、ブロック内で編集可能なフィールドを定義する。

ActiveAdmin.register Item do

  # 編集を許可するフィールドを定義
  permit_params :name, :category, :description

  form do |f|
    f.inputs do
      f.input :name
      f.input :category
      f.input :description
    end
    f.actions
  end
end

フォームコントロールを変更する

商品カテゴリーは自由入力でなく、「カテゴリA」「カテゴリB」「カテゴリC」から選択するようにしたい。その場合は以下のようにinputメソッドにasオプションを指定する。

form do |f|
  f.inputs do
    f.input :name
    f.input :category, as: :select, collection: ['カテゴリA', 'カテゴリB', 'カテゴリC']
    f.input :description
  end
  f.actions
end

ちなみにOptionタグのvalueとラベルを変えたい場合は以下のようにする。

collection: {カテゴリA: :a, カテゴリB: :b, カテゴリC: :c}

補助テキストを追加する

以下のように、フォーム以外の情報を表示することも出来る。

form do |f|
  panel '注意' do
    '商品を追加する場合、同一商品が既に存在しないか確認してください'
  end
  f.inputs '商品新規登録' do
    f.input :name
    f.input :category, as: :select, collection: ['カテゴリA', 'カテゴリB']
    f.input :description
    para "入力内容を確認の上、作成ボタンをクリックしてください"
  end
  f.actions
end

参考

[Mac] Vagrantを2.0.1にアップデートした際のトラブル対応

概要

Macで新しく開発を行うために、既存のVagrant環境のzipを受け取り、環境構築をしようとしたところで幾つかのトラブルに見舞われたのでその解決方法の備忘録を残す。

対応内容とエラーメッセージは以下の通り。

① Vagrantのバージョンが古い問題

This Vagrant environment has specified that it requires the Vagrant
version to satisfy the following version requirements:

>= 1.9.0

You are running Vagrant 1.8.6, which does not satisfy
these requirements. Please change your Vagrant version or update
the Vagrantfile to allow this Vagrant version. However, be warned
that if the Vagrantfile has specified another version, it probably has
good reason to do so, and changing that may cause the environment to
not function properly.

② プラグインが古い問題

Vagrant failed to initialize at a very early stage:

The plugins failed to initialize correctly. This may be due to manual
modifications made within the Vagrant home directory. Vagrant can
attempt to automatically correct this issue by running:

vagrant plugin repair

If Vagrant was recently updated, this error may be due to incompatible
versions of dependencies. To fix this problem please remove and re-install
all plugins. Vagrant can attempt to do this automatically by running:

vagrant plugin expunge --reinstall

Or you may want to try updating the installed plugins to their latest
versions:

vagrant plugin update

Error message given during initialization: Unable to resolve dependency: user requested 'vagrant-vbguest (> 0)'

③ VMの作成者が違う問題

The VirtualBox VM was created with a user that doesn't match the
current user running Vagrant. VirtualBox requires that the same user
be used to manage the VM that was created. Please re-run Vagrant with
that user. This is not a Vagrant issue.

The UID used to create the VM was: 503
Your UID is: 501

前提

以下の環境で動作確認

Mac Book Air 10.12.6
vagrant(更新前) 1.8.6
vagrant(更新後) 2.0.1

Vagrantのバージョンが古い問題

vagran1.8.6で、新しい開発環境用のVMを起動しようとした所、以下のエラーメッセージが表示された。

$ vagrant up
This Vagrant environment has specified that it requires the Vagrant
version to satisfy the following version requirements:

>= 1.9.0

You are running Vagrant 1.8.6, which does not satisfy
these requirements. Please change your Vagrant version or update
the Vagrantfile to allow this Vagrant version. However, be warned
that if the Vagrantfile has specified another version, it probably has
good reason to do so, and changing that may cause the environment to
not function properly.

どうやら対象のVMはvagrant1.9.0以上が要求されているらしいが、Macには1.8.6しか入ってないので起動できないらしい。

VM側を弄るという手もあるが、いつまでも古いバージョンのvagrantを使っていてもアレなので、この機会にvagrantをアップデートする。

Download Vagrantより、Mac用のdmgファイルをダウンロードして、あとは普通にインストールする。

最新版が入った。

$ vagrant --version
Vagrant 2.0.1

プラグインが古い問題

vagrantのバージョンをあげたので、これでVMも起動すると思ったが、今度は以下のエラーが出た。

$ vagrant up
Vagrant failed to initialize at a very early stage:

The plugins failed to initialize correctly. This may be due to manual
modifications made within the Vagrant home directory. Vagrant can
attempt to automatically correct this issue by running:

vagrant plugin repair

If Vagrant was recently updated, this error may be due to incompatible
versions of dependencies. To fix this problem please remove and re-install
all plugins. Vagrant can attempt to do this automatically by running:

vagrant plugin expunge --reinstall

Or you may want to try updating the installed plugins to their latest
versions:

vagrant plugin update

Error message given during initialization: Unable to resolve dependency: user requested 'vagrant-vbguest (> 0)'

どうやらVagrantのプラグインの方のバージョンも引き上げなきゃならない模様。

指示通りプラグインをアップデートする。

$ vagrant plugin update
Updating installed plugins...
Fetching: vagrant-share-1.1.9.gem (100%)
Updated 'vagrant-vbguest' to version '0.15.0'!

こちらの環境ではコレで問題なかったが、updateコマンドが上手く動かない場合、Vagrant 1.9.0に更新したらエラーが発生?を参考に、既存のプラグインを削除すると動くらしい。

VMの作成者が違う問題

今度こそVM起動。と思ったら以下のエラーが出た。

$ vagrant up
The VirtualBox VM was created with a user that doesn't match the
current user running Vagrant. VirtualBox requires that the same user
be used to manage the VM that was created. Please re-run Vagrant with
that user. This is not a Vagrant issue.

The UID used to create the VM was: 503
Your UID is: 501

これは他の人が作成したVagrant用ディレクトリをそのまま受け取った場合に発生しがち。
作成者のUIDと、現在のUIDが違うことで上記のエラーが出るらしい。なので作成者のUIDを、自身のUIDにすることで解決する。

作成者のUIDは、

.vagrant/machines/[VM名 or default]/virtualbox/creator_uid

にあるので、そのファイルを、エラーメッセージに含まれている自身のUID(上記の場合501)に書き換える。

以上の手順でようやく起動した。

$ vagrant up
Bringing machine 'hogehoge' up with 'virtualbox' provider...
==> hogehoge: Box 'hogehoge' could not be found. Attempting to find and install...
hogehoge: Box Provider: virtualbox
hogehoge: Box Version: >= 0
==> hogehoge: Box file was not detected as metadata. Adding it directly...
==> hogehoge: Adding box 'hogehoge' (v0) for provider: virtualbox
hogehoge: Unpacking necessary files from: file:///Users/fuga/hoge/box/hoge.box
==> hogehoge: Successfully added box 'hogehoge' (v0) for 'virtualbox'!

ngrokでvagrantの開発環境に外部からアクセスする

概要

vagrantで立ち上げたVM上(ローカル開発環境)で稼働しているWebサービスに、外部からインターネット越しにアクセスする方法の備忘録。

ローカル開発環境で開発中のWebサービスを、ちょっとだけ他の人に見てもらう際に、サーバにデプロイしたりパソコンを持って相手の元に行ったりするような億劫な作業を改善する。

本記事では、LAN外とLAN内をリレーしてくれるツール(サービス)である、ngrokを用いる。

前提

deban 8.6
ngrok 2.2.8

また、VM内で何らかのWebサービスが3000番で動いていることを想定する。動いているものは何でも良いが本記事ではRailsアプリを使用している。

ngrokについて

ngrokは、LAN外とLAN内をリレーしてくれるツール及びサービス。本来はインターネット越しにアクセスできない閉じた環境に対して、リクエストとレスポンスを中継することで、外部から内部へのアクセスを実現する。

ngrokの料金について

ngrokはフリープランなら無料で、それも会員登録無しで利用できる。フリープランの他にはベーシックプラン、プロプラン、ビジネスプランとランクがあり、それぞれ月額利用料がかかる。

もちろんプランのランクに応じて、よりセキュアな利用ができたり、独自ドメインを使えたり、最大接続数を増やせたりと恩恵が受けられるが、開発環境をサクッと共有したい程度ならフリーで問題ない。

当然本記事ではフリープランを利用する。

ngrokクライアントのインストール

ngrokを、Webサーバが稼働している環境にインストールする。vagrantやdockerを使った仮想マシン上で開発している場合も、ゲストに直接インストールするだけで良い。

64bitLinuxの最新版をダウンロード

$ wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip

zipで落ちてくるので解凍

$ unzip ngrok-stable-linux-amd64.zip

ngrokという単体のコマンドが展開される。これを使うだけ。

$ ls
ngrok  ngrok-stable-linux-amd64.zip

グローバルコマンドにしたい場合はパスが通ってるディレクトリにこれを移動すれば良い

$ mv ngrok /usr/local/bin

ngrokコマンドが使えるようになる

$ ngrok -v
ngrok version 2.2.8

ngrokでローカル開発環境を公開する

3000番ポートでWebアプリケーションが動作している状態で、以下コマンドを実行する。

$ ngrok http 3000

すぐにフォワーディングが開始され、専用URLが発行される

ngrok by @inconshreveable                                                                                (Ctrl+C to quit)

Session Status                online
Version                       2.2.8
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://af23f838.ngrok.io -> localhost:3000
Forwarding                    https://af23f838.ngrok.io -> localhost:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

この場合、ローカル開発環境にアクセスして欲しい人に、”http://af23f838.ngrok.io”にアクセスしてもらえば、ローカル開発環境の3000番ポートにフォワーディングされる。

実際に上記URLにアクセスされると、ステータス200を無事に返却していることがわかる

HTTP Requests
-------------                                                                                   200 OK
GET /favicon.ico                                                                                
GET /                                                                                            200 OK

Ctrl+Cで停止する。停止後は上記URLが以下のように無効になるので、相手の利用が終了するまでは立ち上げたままにすること。

Tunnel af23f838.ngrok.io not found

所感

  • 想像を遥かに超えて簡単に導入、利用できた。比較的古くからあるサービスなのに何故気づかなかったのか。
  • フリープランだとどうしてもセキュリティ的に弱いので、機密情報などが見えてしまうような場合は気をつける必要あり。
  • URLがランダム文字列になると、URLを伝える手間がかかる。月5ドルのプランで独自ドメインが使えるなら組織で契約するのもいいかも

3年目プログラマが参考にしたQiita記事まとめ⑤

概要

特にカテゴリもレベルも偏らずにざっくばらんに、参考になったQiita記事を一言添えて列挙するシリーズ5本目

Qiitaまとめシリーズ

僕が英語でオライリーを読む理由

記事内に出てくる成長曲線的なグラフが心に刺さる。これが事実だとするならもう未経験だけど英語ができる人に追い抜かれる頃だ。何とかして英語力も並行して高めて、追いつかれないようにしないと。

オブジェクト指向と10年戦ってわかったこと

何故誰もオブジェクト指向の本質を説明できないのかといえば、やはりその定義の緩さか。上記記事ではカプセル化をオブジェクト指向の本質と捉えていて、私も概ね同意ではあるが、それを一から説明出来ると言えば微妙なので、まだまだ上辺しか理解できないんだと思う。

責任(関心)を意識したアプリケーション設計

単一責任の原則はまぁ頑張ってるが、関心の分離はイマイチ出来てない自覚がある。どうしても関心が集約してしまうというか、時間的結合みたいなことを高頻度でやってしまう。このあたりをしっかり意識しないと拡張性のあるコードは書けないので改善していきたい。

関数・メソッドの行数を短く保つと色々と捗る件

こういった問題ごとを分割して捉えるって考えはプログラミングに限らず日常作業でも役立つと思ってる。例えば汚部屋を掃除するとしたら、まず掃除区間をわけて、それぞれについてどういった手順で掃除していくかを分割していく。そういうのはプログラマは上手いんじゃないかと思う。

プログラミングでよく使う英単語のまとめ【随時更新】

英単語を知ってることよりも使い分けられることのほうが重要で、例えば追加する系だとadd/put/append/createとかあげられるが、どれが最も適しているかを的確に使い分けられる必要がある。

Go言語で開発がスムーズになった

GoLangどうなんだろう。Googleが積極的に採用してる時点でそうそう廃れることはないけど、Web系でも使える道あるのかな。軽くググってみるとWeb系での活躍も多いみたいだから、時間を見つけて手を出してみたい。

「リーダブルコード適用 チェックリスト」を作ってみました

これは凄い。レビュー用のチェックリストとして使うだけじゃなく、これを一読するだけでもリーダブルコードの恩恵の多くを受けられる。リーダブルコードはプログラマの必読書だと思うが、読む時間がない、読む気力がない人に、これだけでも目を通すように進めたほうが良さそうだ。

ハンバーガーメニューデザインの提案

演出以前に、ハンバーガーメニューはUIとして使いづらい面が多いと思う。何より、ワンタップしないとそのメニューから何ができるかわからないということだ。ユーザが何かをしたい時、一目でそれがわからないというのは辛い。仮にユーザが慣れてきて使い方がわかったとしても、ワンタップ挟まなければそこにたどり着けないというのは辛い。高頻度で利用するメニューについては常に画面上にワンタップで実行できる仕組みを用意したほうが良いと思う。

ウィルスと闘ってみた。

アンチウイルスソフトの類を使わずに、自力でそれを特定して駆除するのは非効率極まりないけど技術力向上のための訓練と思えばかなり良いやりかたかも。戦場に身をおいて鍛えるかのような。

APIドキュメント作成を時短する

記事とはあんまり関係ないけど、ドキュメントを作成するのに専用のツールを使うのは大事かも。最近はドキュメント重視してゴリゴリ書いてるけど、Markdownでチマチマ書くのがかなり面倒なので共通部分はまとめて生成できるようなツールを導入したい。