天泣記

2016-08-30 (Tue)

#1 json の dependency の種類

しばたさんが 「Ruby 2.4.0 で導入予定の Integer Unification まとめ」を書いてくれたので思い立って、add_dependency や add_runtime_dependency で json がどのように指定されているか調べてみた。

gem-codesearch で集めた gem を以下のように検索してデータを集めた。

csearch 'add_runtime_dependency|add_dependency'|egrep -o "('json'|\"json\"|%q<json>).*"

これをもとに requirements のところだけ取り出して形式を整えるなど (エディタで) 掃除してきれいにした。

数を数えて上位を表示してみると以下のようになる。(nothing は add_dependency に requirements を指定していないものである。)

% sort 2016-08/json-dependency.csv|uniq -c|sort -nr|head
   1731 "nothing"
   1298 "'>=0'"
    366 "'~>1.8'"
    119 "'>=1.4.6'"
     97 "'~>1.8.1'"
     83 "'>=1.1.3'"
     73 "'~>1.4'"
     69 "'~>1.8.0'"
     69 "'>=1.4.3'"
     60 "'>=1.2.0'"

グラフにしてみると以下のようになる。

json-dependency.R:

library(ggplot2)
d <- read.csv("2016-08/json-dependency.csv")
d$detail <- "exact"
d$detail[grep("nothing", d$requirements)] <- "any"
d$detail[grep(">", d$requirements)] <- "optimistic"
d$detail[grep("<", d$requirements)] <- "pessimistic"
d$detail[grep("~", d$requirements)] <- "pessimistic"
d$type <- "optimistic/any"
d$type[d$detail == "exact"] <- "pessimistic/exact"
d$type[d$detail == "pessimistic"] <- "pessimistic/exact"
p <- ggplot(d, aes(type)) + geom_bar(aes(fill=detail))
print(p)

json-dependency.png

以下のように分類したつもりである。

json が Ruby 2.4 対応 (Integer Unification 対応) と同時に 2.0.0 にバージョンをあげた (major version up) ことにより、使えるバージョンの上限を指定しているもの (大きく version up したら動かないかもしれないから使わないという悲観的な指定をしていたもの) は Ruby 2.4 対応のために dependency の更新が必要になった、ということだろう。

なお、特定のバージョンを要求するものもあるが、多くはない。

json がなぜ major version up したのかというと、RFC 7159 対応とか Ruby 1.x サポート終了とか大きな変更が入ったからだろうか。

さらに json に依存する gem の更新時に大きく version up をされるとそっちでも同様な話が起きるというのが rdoc や ActiveSupport の話かな。

なんというか、バージョンを指定する、というやりかたが間違っているような気もする。

2016-08-18 (Thu)

#1 Coq Bug 5023 を報告した

Coq Bug 5023 - JSON extraction doesn't generate 'for xxx' part of local mutually recursive functions

2016-08-15 (Mon)

#1 ショクダイオオコンニャク

国立科学博物館筑波実験植物園で、ショクダイオオコンニャクが咲いたというので見に行ってみた。

2016-07-02 (Sat)

#1 SP会

Unix domain socket APIのポータビリティ問題」というのを発表した。

テストに使ったソース: <URL:https://github.com/akr/socket-test>

2016-06-29 (Wed)

#1 「幸せな未来は「ゲーム」が創る」を読んだ

ゲーミフィケーションの話。幸せは低コストで作れるし、そうなっていないものは良くデザインされていないということだと思った。

2016-05-28 (Sat)

#1 東京Ruby会議11

東京Ruby会議11にいってきた。

2016-04-16 (Sat)

#1 いろいろな sum メソッド

Ruby 2.4 には Array#sum メソッドが入るのだが、sum メソッドはすでにさまざまな gem が提供している。いくつかの実装を比べてみよう。

activesupport-4.2.6:

module Enumerable
  def sum(identity = 0, &block)
    if block_given?
      map(&block).sum(identity)
    else
      inject { |sum, element| sum + element } || identity
    end
  end
end

facets-3.0.0:

module Enumerable
  def sum(*identity, &block)
    if block_given?
      map(&block).sum(*identity)
    else
      reduce(*identity) { |sum, element| sum + element }
    end
  end
end

simple_stats-1.1.0:

module Enumerable
  def sum(&block)
    return map(&block).sum if block_given?
    inject(0) { |sum, x| sum + x }
  end
end

production_log_analyzer-1.5.1:

module Enumerable
  def sum
    return self.inject(0) { |acc, i| acc + i }
  end
end

hash-utils-2.2.0:

class Array
  def sum
    self.inject(:+)
  end
end

gcstats-1.0.4:

class Array
  def sum
    inject {|a, e| a + e }
  end
end

gauntlet-2.1.0:

class Array
  def sum
    sum = 0
    self.each { |i| sum += i }
    sum
  end
end

さまざまな実装があることがわかる。

こうもいろいろとあると、実は今までにも互換性の問題が発生していたかもしれないな。

Ruby 2.4 では (現在の実装では) Array に定義して、与えられたブロックは適用し、要素がなかったときの値を指定でき、指定しなければ 0 を返し、指定した場合は結果に加えられる。まぁ、ブロックを使わない (無視する) ようにすると、エラーもなく値が変わって不幸だし、map するように変えるのは呼出側のコードが長くなっちゃうしな。要素がなかったときの値は悩みどころだが、結果に加えた方が仕様の中の場合分けが少なくなるのでいいだろう。



田中哲