読者です 読者をやめる 読者になる 読者になる

日常

ケ・セラ・セラ

RailsでRuby2.4のHash#compactを使うp-rがある

ruby ruby24 rails

読みました。短くまとめます。

これがマージされると、Ruby 2.4 で加わる Hash#compact / Hash#compact! を Rails でも使うようになる。

Hash#compact が無い環境では、従来どおり activesupport 版を使うような変更ですね。

# activesupport/lib/active_support/core_ext/hash/compact.rb

+  unless Hash.instance_methods(false).include?(:compact)
+    # Returns a hash with non +nil+ values.
+    #
+    #   hash = { a: true, b: false, c: nil }
+    #   hash.compact        # => { a: true, b: false }
+    #   hash                # => { a: true, b: false, c: nil }
+    #   { c: nil }.compact  # => {}
+    #   { c: true }.compact # => { c: true }
+    def compact
+      select { |_, value| !value.nil? }
+    end

Ruby 2.4 の Hash#compact #compact! は C 実装です。ActiveSupport 版に比べて速くなるでしょう。

yaml_checker という Gem を作りました

ruby gem yaml

github.com

https://rubygems.org/gems/yaml_checker

ファイル名かディレクトリを指定すると、.yml / .yaml 拡張子のファイルのみ YAML.load_file して回って、例外を起こしたものをまとめて標準出力する。というやつです。

$ yaml_checker path/to/directory
$ yaml_checker path/to/directory/foo.yml
$ yaml_checker path/to/directory/bar.yaml

invalid なファイルを含む時の様子です。

$ yaml_checker examples/
(/path/to/examples/dir1/dir2/invalid.yml): did not find expected key while parsing a block mapping at line 1 column 3
(/path/to/examples/dir1/invalid.yml): did not find expected key while parsing a block mapping at line 1 column 3
(/path/to/examples/invalid.yml): did not find expected key while parsing a block mapping at line 1 column 3
(/path/to/examples/dir1/dir2/invalid.yaml): did not find expected key while parsing a block mapping at line 1 column 3
(/path/to/examples/dir1/invalid.yaml): did not find expected key while parsing a block mapping at line 1 column 3
(/path/to/examples/invalid.yaml): did not find expected key while parsing a block mapping at line 1 column 3

もう少し機能的に色々考えていて書き始めたのですが、とりあえずこれだけあればいいかという気持ちになってきて公開しました。必要が生じたらまたという気持ちです。

capybara, poltergeist, phantomjs で js: true なテストをする

rspec rails test capybara poltergeist

save_and_open_page や save_screenshot する場合には、 html の charset が設定されていないと日本語が文字化けてしまいました。 そういう場合には書きましょう。

<meta charset="UTF-8" />

まず install phantomjs (Ubuntu での例です)

$ wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
$ sudo cp -ip phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/
$ phantomjs --version
2.1.1

Gemfile

group :test do
  gem "capybara"
  gem "launchy" # save_and_open_page するなら
  gem "poltergeist"
end

rails_helper.rb

require "capybara/poltergeist"
Capybara.javascript_driver = :poltergeist

sample feature spec

# sample_spec.rb
require "rails_helper"
RSpec.describe "Sample", :type => :feature do
  before do
    visit foo_path
  end

  feature "bar" do
    senario "baz", js: true do
      click_link "baz"

      # target: "_blank" な場合は別 window になる
      within_window(switch_to_window(windows.last)) do
        expect(current_path).to eq("/foo/bar/baz")
        expect(page).to have_content "some content"

        # save_page("save.html")
        # save_and_open_page
        save_screenshot "screenshot-#{DateTime.now}.png"
        # 全画面とりたい場合は full: true で
        save_screenshot("screenshot-#{DateTime.now}.png", full: true)
      end
    end
  end
end

save_and_open_page で js, css も反映されたい場合、 assets が localhost で完結している場合には別途 rails s しておいて、 rails_helper.rb などに以下の様に設定しておくというのが簡単かなあと思いました。

Capybara.asset_host = "http://localhost:3000"

trelloのカードの並び順みたいなのをどう実装しているか

trello

trello clone 的なやつを作っているんですが、

drag & drop でカードの並び替えとかした時の並び順をどう管理しようかと考えていた。

そこで trello の動きをちょっと見てみたらこんな感じだった。

たとえばこんな風に、あるリストに 3つのカードが登録されていたとする。

  • list
    • card1
    • card2
    • card3

まずこうしてみたところ、card3 を PUT してる内容を見ると、 pos という項目に 57344 という値が見られた。うむ、position ぽい。

  • list
    • card1
    • card3
    • card2

ふたたびこうしてみる。card2 の PUT では pos: 53248

  • list
    • card1
    • card2
    • card3

また繰り返すと、pos 値は 51200, 50176 と変化した。変化量を追うと、 -4096, -2048, -1024 ... ということのようだ。

では以下のように card4 を追加してみる。pos: 116736 だった。

  • list
    • card1
    • card2
    • card3
    • card4

さらに card5 を追加すると、pos: 182272。card6 は 247808。

この値は、最後のカードの pos + 65536 のようだ。

リロードして、card7 を追加してみると、同様に 313344 だった。

216 空けておけば妥当なのかな。16回繰り返したらどうなるんだろうと思ってやってみたら、

215040, 198656, 190464, 186368, 184320, 183296, 182784, 182528, 182400, 182336, 182304, 182288, 182280, 182276, 182274, 182273, 182272.5, 182272.25

なるほど、小数になるわけだ。

というわけでこういう実装をすることに決めた。

Rails5でforce_sslのredirect status, HSTS header のコントロールが便利になる

force_ssl rails5

読んだので簡単にまとめてみる試み。force_ssl 関連。

RailsHTTPS を強制する config.force_ssl = true' を設定すると、middleware stack にActionDispatch::SSL` が挿入されるわけだけれど、ActionDispatch::SSL は3つの責務を担うね。

  1. http request を https request に redirect する
  2. browser に伝えるために secure flag をセットする
  3. response に HSTS ヘッダを追加する

Rails 5 からは HTTP status を指定することができる(default: 301)。

refs.

config.force_ssl = true
config.ssl_options = {  redirect: { status: 307, port: 81 } }

こちらがマージされて、non-(GET or HEAD) なリクエストの場合には default で 307 となった

HSTS header の preload directive や、max-age の設定はこのようにできる

config.ssl_options = { hsts: { preload: true } }
config.ssl_options = { hsts: { expires: 10.days } }

Rails5 では false にすると expires には 0 がセットされ、HTTPS として扱わなくなる

config.ssl_options = { hsts: false }

querySelectorとJQueryでcssをいじるメモ

querySelector で

foo = document.querySelector("#bar li a.baz");
color = foo.style.color;
bg_color = foo.style.backgroundColor;
foo.style.color = bg_color;
foo.style.backgroundColor = color;
foo.style.borderStyle = "solid";
foo.style.borderWidth - "1px";
foo.style.float = "right";

JQuery

foo = $("#bar li a.baz")
color = foo.css("color")
bg_color = foo.css("background-color")
foo.css("color", bg_color)
foo.css("background-color", color)
foo.css("border-style", "solid")
foo.css("border-width", "1px")
foo.css("float", "right")

転職ドラフト登録してみている

diary

おもしろそうと思って今まさに登録してみているけれど、登録に際していくつか入力することがあって、入力しながら色々と考えることもあったので書き残しておこうと思う。

自信を持って人より秀でていると言える点は? という質問があって、選択肢から最大 3つ選択するみたいなのがある。こんな感じの選択肢。

学習能力 企画立案力 プレゼン力 分析力 調整力 問題解決力 交渉力 責任感 巻き込み力 経営判断力 営業力 人を集める力

人より秀でているって何だろう。自分が得意と思う分野を選択するわけではなくて、人より秀でていると言える点かー。それはもっと各選択肢を細分化した内の1つになるだろうなー。みたいな感じなので、これら選択肢には "主語が大きい" に似た印象を持ってしまい、結局どれも選択出来なかった。しかしまあ、どれが長所なのか?という問いなんだとは思う。

水とプログラミングどっちが大事? そんなの水に決まってるだろ。

"OSSのコミッターである" という項目については、全然無名OSSだけどなと思いつつチェックした。もっとどうにかしていきたいものです。