Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ(20190408-1/2前編)RubyKaigiの予習資料、Rails「今年ベストのプルリク」、numbered parametersの議論ほか

こんにちは、hachi8833です。とうとうGoogle Plusが終わってTechRacho記事の上のG+ボタンが消えましたが、Inbox By Gmail(iPhoneアプリ)まで終了とは油断でした😇。


つっつきボイス:「Google Plus終わりましたね👋」「ひと月ぐらい前からG+ボタンがひとりでに消滅しました😇」「公式のG+ボタンだからでしょうね☺️: 自分でカスタマイズしているボタンだと消えなさそう」

「ところでGoogle Plusの終了対応やった人います?」「やってないかな〜」「お、私はサイトからGoogle Plusのauth login外す作業やりました😆」

  • 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください

4/4(木)の第9回 公開つっつき会には7名のゲストが参加し、BPS社員も交えてこれまでで最大の賑わいとなりました。本当にありがとうございます😂!

Rails: 先週の改修(Rails公式ニュースより)

公式の更新情報のいくつかは、先週のウォッチで@jeremy氏のキーノートで先回りしましたので、それ以外のものを取り上げました。

「今年ベストのPR」

と公式の更新情報に書かれていました。

"foo123".html_safe.sub(/([a-z]+)([0-9]+)/) {
  $2 + $1 #=> undefined method `+' for nil:NilClass (NoMethodError)
}

つっつきボイス:「今年ベストと!」「@shugoさんによるActive Supportの機能追加なんですが、#subとかで正規表現の$1みたいな後方参照(back reference)が効いていなかったのが効くようになったそうです」「後方参照をそもそも使ったことがなかった😆」「やりたい人はいそう」「上↑みたいなのはやりたい場合があるかも!」「@amatsudaさんがRubyらしい修正方法ととても喜んでました」「自分でそれ用のメソッド書くより(・∀・)イイ!!」

Ruby: 正規表現の後方参照を「正しく」エスケープする方法(翻訳)

roflscalingを削除

# activerecord/lib/arel/visitors/mssql.rb#L109
-           inject_join o.wheres, collector, AND
+           inject_join o.wheres, collector, " AND "

つっつきボイス:「修正そのものは単純なんですが、このroflscalingという言葉がどこから来たのかが謎で🤔、roflを何度もrolfと書き間違えました😅」「あーなるほど、何を変えたかはコード見ればとてもわかりみ😋: 由来はわからんけど😆」「全然わからない😅」「謎すぎ😅」「プルリクで挙動については説明してくれていますね↓」

roflscaling (using frozen string constants instead of literal strings)

「どうも8年前のRedditの書き込みと動画↓が関連しているようで、その時期にバズったジャーゴンか何かのようです」

いかにもな機械音声でゆっくろいどを思い出しました。

「更新前のドキュメントでInstructionSequenceとか使ってる↓し、インストラクションレベルのすごーく微細な部分の最適化をroflscaleって呼んでるのかな?」「roflscaleしたことでかなり速くなってたのか😳」「Rubyのfrozen string literal化でそれが不要になったということみたいですね」

# activerecord/lib/arel/visitors/to_sql.rb#L20
-     # > puts RubyVM::InstructionSequence.new('def foo; "bar"; end').disasm
-     #
-     #   == disasm: <RubyVM::InstructionSequence:foo@<compiled>>=====
-     #    0000 trace            8
-     #    0002 trace            1
-     #    0004 putstring        "bar"
-     #    0006 trace            16
-     #    0008 leave

公式の見出しで「Stop ROFL」とあるのはダブルミーニングのようです。上の動画の「101」は、いわゆる「〜入門」「〜のいろは」を表すそうです(大学の最初の授業番号が101であることが多いのが由来)。

ROFL: 床を転げ回って爆笑(rolling on the floor, laughing)🤣

ネイティブもroflscaleが何なのか首を傾げている↓みたいです。

1001年3月7日以前のTime#advanceを修正

修正前:
Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-05 00:00:00 UTC
修正後:
Time.utc(1001, 3, 6).advance(years: -1) # => 1000-03-06 00:00:00 UTC

# activesupport/lib/active_support/core_ext/time/calculations.rb#L162
  def advance(options)
    unless options[:weeks].nil?
      options[:weeks], partial_weeks = options[:weeks].divmod(1)
      options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
    end
    unless options[:days].nil?
      options[:days], partial_days = options[:days].divmod(1)
      options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
    end

-   d = to_date.advance(options)
-   d = d.gregorian if d.julian?
+   d = to_date.gregorian.advance(options)
    time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
    seconds_to_advance = \
      options.fetch(:seconds, 0) +
      options.fetch(:minutes, 0) * 60 +
      options.fetch(:hours, 0) * 3600
    if seconds_to_advance.zero?
      time_advanced_by_date
    else
      time_advanced_by_date.since(seconds_to_advance)
    end
  end

つっつきボイス:「1001年3月7日以前のTime#advance😆」「グレゴリオ暦より前の時代の誤差みたいですね」「ははぁ」「Time.utc(1001, 3, 6).advance(years: -1)が3月5日になっていたのね」「こーゆーのはカレンダーに詳しい人にお任せしたい😆」

参考: Time#advance
参考: グレゴリオ暦 - Wikipedia

Railsコンソールのsandboxをオフにするオプションを追加

  • config.disable_sandboxは、コンソールをsandboxモードで起動できるようにするかどうかを制御する。sandboxコンソールを開きっぱなしにするとデータベースサーバーのメモリがなくなる可能性があるため。

つっつきボイス:「sandboxモード(rails console --sandbox)ってそんなのがあるんだ?!」「コンソールでデータベースに書き込んでも大丈夫なように、コンソールを閉じたらロールバックするモードみたいです」「コンソールセッション自体が1つのトランザクションになるモードか!」「たまに使ったことあるかも」「あ〜たしかに本番で不用意にsandboxモードで入りっぱなしにするとデータベースが落ちて死ぬかも😆」「コマンド一発でサーバー止めて嫌がらせできるヤツだ😆: たしかにそういうのはproductionで防止すべき」

ビューのエラーメッセージ表示を改善

修正前:

修正後

同PRより


つっつきボイス:「これは画像で一目瞭然」「自分はこういうコミットとってもありがたいと思う🙏」「ですね〜」「エラーメッセージを見ればどうしたらいいかがわかるというのはとてもスバラシイ👍」「スタックトレースどんどん深くなりがちだし」「最近のRubyだとTracePointで追いやすくなってたりしますしね」

# actionview/lib/action_view/template/error.rb#L148
+   def message
+     <<~MESSAGE
+       Encountered a syntax error while rendering template: check #{@offending_code_string}
+     MESSAGE
+   end

参考: class TracePoint (Ruby 2.6.0)

descendants trackerの参照をGCされやすくした

# activesupport/lib/active_support/descendants_tracker.rb#L68
+   class DescendantsArray # :nodoc:
+     include Enumerable
+
+     def initialize
+       @refs = []
+     end
+
+     def initialize_copy(orig)
+       @refs = @refs.dup
+     end
+
+     def <<(klass)
+       cleanup!
+       @refs << WeakRef.new(klass)
+     end
+
+     def each
+       @refs.each do |ref|
+         yield ref.__getobj__
+       rescue WeakRef::RefError
+       end
+     end
+
+     def refs_size
+       @refs.size
+     end
+
+     def cleanup!
+       @refs.delete_if { |ref| !ref.weakref_alive? }
+     end
+
+     def reject!
+       @refs.reject! do |ref|
+         yield ref.__getobj__
+       rescue WeakRef::RefError
+         true
+       end
+     end
+   end
  end

WeakRefというライブラリを初めて知りました。

参考: class WeakRef (Ruby 2.6.0)

weak reference を実現するクラスです。
WeakRef オブジェクトは与えられたオブジェクトをポイントしますが、 ポイント先のオブジェクトは GC される可能性があります。 アクセスしようとしたときにオブジェクトが GC されていれば WeakRef::RefError が発生します。
delegate も参照してください。
docs.ruby-lang.orgより

Rails

Active StorageとGraphQL


つっつきボイス:「でたGraphQL😆」「この中でGraphQL使ってる人っています?」「たぶんhello worldレベルぐらい😅」

RailsでGraphQL APIをつくる: Part 1 – GraphQLとは何か(翻訳)

「GraphQLってどうなんだろって思うことしばしば😆」「その点yancyaさんがRailsdm 2019でも発表したSQLQL↓はとてもわかりみ: 何といっても新言語覚えなくていいし😋」「GraphQL、飛び乗っていいのかどうか皆さん様子見してる感🚢」「あくまで予感ですが、新言語作るより既存のものをsafeな何かにする方がよさげっぽい気はしますけどね」

「で記事のタイトルだけ見るとActive RecordじゃなくてActive StorageでGraphQLしてるみたいなので、抽象化とかそのあたりの話かな?」


同記事より

「こういうGraphQLクエリ↓を投げると」

// 同記事より
mutation {
  createDirectUpload(input: {
    filename: "dev.to", # file name
    contentType: "image/jpeg", # file content type
    checksum: "Z3Yzc2Q5iA5eXIgeTJn", # checksum
    byteSize: 2019 # size in bytes
  }) {
    directUpload {
      signedBlobId
    }
  }
}

「このあたり↓がメタデータを投げるところに関連してそうで、それで取ったものを使ってdirect uploadするとかそんなノリっぽい」

# 同記事より
class CreateDirectUpload < GraphQL::Schema::Mutation
  class CreateDirectUploadInput < GraphQL::Schema::InputObject
    description "File information required to prepare a direct upload"

    argument :filename, String, "Original file name", required: true
    argument :byte_size, Int, "File size (bytes)", required: true
    argument :checksum, String, "MD5 file checksum as base64", required: true
    argument :content_type, String, "File content type", required: true
  end
...

「そういえばこの記事を書いているEvil Martians↓はTechRachoでもちょくちょく翻訳記事を出していて、あといろんなgemのスポンサーをやってたりしますね」「悪い火星人👽」

evilmartians.comより

TestProf: Ruby/Railsの遅いテストを診断するgem(翻訳)

関係ありませんが、Mars Attacks!(1996)で地球人に化けた火星人役のリサ・マリーの「人間以外の何か」感満載の演技が好きです↓。

参考: マーズ・アタック! - Wikipedia

ActiveRecordExtended: PostgreSQL向けのAR拡張(GitHub Trendingより)

しばらく見てなかったGitHub Trendingが何だかノイズが増えてて残念です😢。


つっつきボイス:「PostgreSQL専用みたいです」「ぽすぐれにしかない機能を使えるgemってことか」

「ANYなんてのが↓」「あーなるほど、文字通り『どれかに該当』みたいなのが取れるのか」「ALLはtags: 1だけのものを指すと」「このあたりはexpressionですね🧐」

# 同リポジトリより
alice = User.create!(tags: [1])
bob   = User.create!(tags: [1, 2])
randy = User.create!(tags: [3])

User.where.any(tags: 1) #=> [alice, bob] 

alice = User.create!(tags: [1])
bob   = User.create!(tags: [1, 2])
randy = User.create!(tags: [3])

User.where.all(tags: 1) #=> [alice] 

「OVERRAP?」「文字通りオーバーラップを取れる」

# 同リポジトリより
alice = User.create!(tags: [1, 4])
bob   = User.create!(tags: [3, 4])
randy = User.create!(tags: [4, 8])

User.where.overlap(tags: [4]) #=> [alice, bob, randy]
User.where.overlap(tags: [1, 8]) #=> [alice, randy]
User.where.overlap(tags: [1, 3, 8]) #=> [alice, bob, randy]

inet_containなんてのが😍: こういうのを自力でやろうとすると超大変😭」「すげー、IPアドレスのマッチングできるなんて」「特にIPv6のマッチングとか自力でやりたくないし🤣」「🤣」「ぽすぐれはこういうこととかいろんなことできるから😆」「ここまで容赦なくいろんな機能使えるとは👺」

# 同リポジトリより
alice = User.create!(ip: "127.0.0.1/16")
bob   = User.create!(ip: "192.168.0.1/16")

User.where.inet_contains(ip: "127.0.0.254") #=> [alice]
User.where.inet_contains(ip: "192.168.20.44") #=> [bob]
User.where.inet_contains(ip: "192.255.1.1") #=> []

参考: IPv6 - Wikipedia

「RubyにもこういうIPアドレスマッチング欲しいです」「そういうのはRDBMSでやった方が断然速いですね🧐」「★ポチっておこうっと」

その他Rails


つっつきボイス:「はてブで見つけました」「そうそう、この記事は結構好き❤️」「王道を行くアドバイスですね」「新人エンジニアが教わる定番の内容」「『そんな感じ』で終わるあたりがまた😆」

「新人から同じ質問が何度も来たりすると、Google検索で使えるキーワードだけ貼ったりすることあるし🤓」



つっつきボイス:「kamipoさんの絞り出すようなツイートです」「↑えぇ〜?!こんな挙動するってマジで😱」「ぽすぐれの謎仕様というか何というか😅」「ぽすぐれならありそうといえばありそう😅」

Ruby


rubykaigi.orgより

RubyKaigiも近くなってきましたね。軽く過去リンクを貼ってみました。


つっつきボイス:「外部参加の皆さんの中で今度のRubyKaigi 2019に行く人っています?」(軽く挙手)「なるほど2名」「ぜひ現地で😋: ちなみに自分は火曜日ぐらいから現地入りします😎」「あ〜そうすればよかった!: RubyKaigi始まったらもう落ち着いて飲み食いする暇ないし🍶」「気持ちの9割ぐらいは飲みに行くつもりで😆」

RubyのProc.newprocは使われなくなりつつある?


つっつきボイス:「最近Quoraの回答が面白くてしょうがないです🍰」「そういえば最近Proc.newとかあまり見かけなかったかも?」「自分もそのあたりがしょっちゅうわからなくなってたんですが、ある意味究極の回答↓があったので」

その後、ブロック引数(&引数)が導入されることで Proc.new の必要性が薄れ、lambda式(->)が導入されることで、lambdaprocメソッドの必要性が薄れ、それらは現在ではほとんど使われなくなっています。たぶん、将来これらのメソッドは削除されるでしょう。Rubyの歴史による変化を感じさせますね。
Quoraより

「普段意識することはほとんどないけど、たしかそれぞれ少しずつ動作が違うんですよね」「引数の個数の扱いとかそのあたりが少し違ってたと思います」

参考: 【Ruby】ブロック・Proc・lambda を理解する - Qiita

Ruby VMの中はこうなっている

昨年の記事ですが。


つっつきボイス:「RubyKaigiはVMとかの内部構造の話がよく出てくるので、このあたりの記事とか『Rubyのしくみ』が予習にいいかと思って」「そうそう、RubyKaigiはこのあたりを押さえてから望まないとマジ何言ってるかわからなくなったりするし🤓」

Ruby Code → Tokenize → AST → YARV Inst → Execute
Medium記事より

「ところで今日の参加者の方でこれまでRubyKaigiに参加経験ある人っていらっしゃいます?」「お、いらっしゃらないということは今回が初なんですね」「☺️」「RubyKaigiのこの辺の話は普段触れる機会がなかなかない分わけわかんなくて楽しいっすよ〜🤣」「そうそう🤣」「それが楽しみ🤣」

「RubyKaigiは『Rails』という言葉がめったに出てこないという特徴があってですね🤣」「🤣」「🤣」「まあRailsは他のカンファレンスがいくらでもあるので、RubyKaigではRuby本体の方にフォーカスしようとかそういうノリだと思いますが☺️」「とはいえRailsの話もするときはしますけど😋」

「ともあれ、RubyKaigiではRubyのVM関連の用語は軽く押さえておく方がいいでしょうね」「特に英語のセッションとかで音声で聞くときには、YARV(ヤルヴ)みたいな用語を発音でも知っておかないと焦りますね」

「一応今日のつっつき会にも『Rubyのしくみ』こと『Ruby Under Microscope』という真っ赤な本↓を持ってきました🍓」「この本読んどけばどうにかなりますね😋」「内容は少し古くてRuby 1.9とか2.0とかそのあたりなんですが、基本は変わってないはずです」

「Rubyという言語は割とVMの話をしてくれる人が多いのが特徴かもしれない」「RailsウォッチでもVMの話題はよく取り上げているので、普段から何となくでも読んでいると違うかもしれないです😋」「『よくわからないということがわかった』ぐらいにはわかるかと😆」「😆」「ではまずVMとは何かから🤣」

「それか、るびま記事『YARV Maniacs』↓とかTechRachoでRVALUEが出てくる記事↓あたりをざざーっと読んでおくといいかもです」

参考: YARV Maniacs 【第 1 回】 『Ruby ソースコード完全解説』不完全解説
参考: YARV Maniacs 【第 2 回】 VM ってなんだろう -- 以下12回まであります。

Rubyのヒープをビジュアル表示する(翻訳)

RubyとLispといろんな言語


つっつきボイス:「そうそう、Eiffelもあった🗼」「CLUという言語も初めて見たんですが👀、リンクをたどるとMatzが『実は動かしたことはないんです』『でも影響を受けたのは本当なんです』と書いてました😆」「言語マニアの鑑(かがみ)」

参考: Eiffel - Wikipedia


ja.wikipediaより

参考: Rubyist のための他言語探訪 【第 2 回】 CLU

「ちなみに言語そのものが好きっていう方はいます?」「『7つの言語 7つの世界』↓を読んだぐらいかな〜」「お、そんな本があるんですか?!」「監訳がMatzだ」「言語に対しての考え方がいろいろあって楽しい本でした😍」

「ちなみにQuoraって何でしたっけ?」「Quoraは5年ぐらい前に英語圏で爆発的に流行った、Yahoo!知恵袋的なQ&Aサイトですね😆」「わかりやすい😆」「Yahoo!知恵袋😆」「最近やっと気づいたんですが、Quoraは質問はすべて匿名で、回答者は実名かつ所属を明らかにするというルールなんですね」「そこが知恵袋との違い😆」


jp.quora.comより

「Quoraが面白いのは、強いエンジニアが登録していることが多くて、何か技術的な質問をすると運がよければサービスやってる中の人とかCTOとかが答えてくれたりするところですね」「あ〜そうかも!」

「日本語版は数年前に始まったのがずっと鳴かず飛ばずだったのに、ここにきて急に人気が出てきた感ありますね☺️」「Quoraだと相当初歩的な質問でもしやすい雰囲気ができつつあるみたいです」「こうやって専門家が熱心に回答するようになると盛り上がってくるんでしょうね🥰」「ちなみにQuoraはGoogleの検索にひっかからないように検索除けされてます🤖」

「あとQuoraの英語版は検索機能がものすごくよくできてる」「おぉ〜」「英語版の自然言語検索はヤバいぐらいどんぴしゃりな結果出ますね: でも日本語版はどうだろう🤔」(少し試す)「うん、まだまだ😆」「😆」「お、ちょうど知人がQuoraで回答してる!: 神奈川県で一番Unicodeに詳しい人です😆」「神奈川県😆」「日本でとか東京でと言い切るのはおこがましいので、だそうです😆」

mapknitter:航空写真貼り付けgem(GitHub Trendingより)


つっつきボイス:「Rubyで書かれてるそうです」「まっぷにったー?」「knitは編み物のニットっぽいですね」

knit: 編む, 編み物をする、接合する

「で、どうやらいろんな人がドローンとかで撮影した航空写真を以下のサイトにみんなで貼り貼りして地図を作っちゃおうということみたいです」「バルーンとか凧とかも使ってインスタグラム的にやっちゃおうみたいな」

「自分が学生の頃にやってたセンサーネットワーク↓をちょっと思い出した: アメリカの農業とかって人間がすべて監視するのが不可能なぐらい広いから、種も農薬も飛行機で撒いたりするじゃないですか」「あ〜」「そういうアメリカン🇺🇸なプロジェクトをこのmapknitterに感じてしまうんですよね😆」「またの名を大雑把😆」「集約的農業の逆ですね」

参考: センサネットワーク - Wikipedia


ja.wikipediaより

参考: 集約農業 - Wikipedia

その他Ruby


つっつきボイス:「技術書典に出すみたいです」「igaigaさん、こんだけたくさん書いてるのはやっぱすげ〜😍」「スゴいです👍」

「技術書典って一度行ってみたいんですが、まだその機会がなくて😅」「技術書典、死ぬほど人が多過ぎるという話😎」「死ぬほど人が多過ぎます😇」「やっぱり〜😭」「それで諦めたことあるし」

「私のときは入場制限かかりましたよ🚫」「そんなに!」「人混みも並ぶのもキライなのでVRで参加したい🤣」「無理だけどわかる〜😆」

Ruby trunkより

numbered parametersを考え直したい


つっつきボイス:「やっぱりnumbered parameterが😆」「やっぱり議論に😆」

「これは何でしょう?」「先週のウォッチでもちょっと話題になったんですが、Ruby 2.7でeachとかのブロックの中にこうやって@1↓みたいに書けるというヤツです」「ブロック引数の名前がわからなくても参照できるみたいな」

# 同issueより
[1, 2, 3].each { |i| puts i }

# 上を以下のように書けるのがnumbered parameters

[1, 2, 3].each { puts @1 }

「詳しくはまだわかんないけどアツいことができそうな雰囲気🌋」「『だらしない書き方』という声もあるみたいです😆」「Rubyをワンライナーで書くときにはちょっと便利そうな気もするけど🤔」

「さすがに@1は考え直そうよみたいな話なのかな」「え、元々itだったのか!」「ちょ😆」「thisとかself的な😆」「RubyがRSpecっぽくなりそうな予感するんですけど🤣」

「さすがissueのスレがめっちゃ伸びてる!🐍」「当分動いてそうなスレですね 」

「ちなみに以下の記事もnumbered parametersについてでした」

map { @1 + @2 + @3 }みたいに書けると」「なるほど」

# 同記事より
# 現状
[1, 2, 3].each { |i| puts i }
(1..10).map { |i| i * 3 }
(1..9).each_slice(3).map { |x, y, z| x + y + z }

# Ruby 2.7
[1, 2, 3].each { puts @1 }
(1..10).map { @1 * 3 }
(1..9).each_slice(3).map { @1 + @2 + @3 }

「でもこういうの↓とか、ブロックの中でさらにブロックみたいな複雑なのになってきたらややこしそう😅」「使いこなせるかしら...😅」「自信ないっす😭」

# 同記事より
h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }

# vs

h = Hash.new { @1[@2] = "Go Fish: #{@2}" }

「numbered parameters、もしかすると今度のRubyKaigiで大喜利のお題になったりして?」「話題には出てきそう😋」

そういえば以下のyield_self↓が、前回のRubyKaigiの場で『エイリアスはthenになりました』と発表されましたね。

Ruby 2.5の`yield_self`が想像以上に何だかスゴい件について(翻訳)

RubyVMをCRubyにリネームしてはどうか


つっつきボイス:「あー、MatzのRubyをどう呼ぶかか😵」

「たしかに、C言語で書かれたRubyはMRIって呼ばれてましたよね」「そのはずです」「もしかすると最近はCRubyって呼ばれることが増えてたりする気がする: 気がするだけですが😆」「気にしたことなかったけど、もしかするとMatz以外にもC言語でRubyを実装した人がいるのかも?」

参考: Ruby MRI - Wikipedia -- CRubyはMRIと同じもののようです
参考: CRuby以外のRuby実装について調べたよ - Qiita

「MRIは Matz's Ruby Implementationでしたっけ」「CRubyの方がJRubyとかと対比しやすいからかしら?」「お、RubyKaigiで出てきそうなキーワードがissueにいくつかありますね↓」「JRubyとかTruffleRubyの人はよくRubyKaigiに来ますし」「TruffleRubyはめちゃ速いという話」「rbenv install -lとかやるとこの辺の実装もリストに出てきますね😆」


今回は以上です。

バックナンバー(2019年度第1四半期)

週刊Railsウォッチ(20190402-2/2後編)Apache Arrowとは何か、prop drillingはアンチパターン、Node-REDほか

今週の主なニュースソース

ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSなど)です。

Rails公式ニュース

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Publickey

publickey_banner_captured

GitHub Trending

160928_1701_Q9dJIU


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。