すがブロ

sugamasaoのhatenablogだよ

Rubyのnilクラスを調べたい

nilクラスが実際にどうなってるのか調べたい

Rubyの実装がどうなっているか、一年に365回くらいは調べたくなると思うのですが、今日はnilクラスについて調べました。

Rubyの組み込みクラスは(多分)リポジトリ直下にそれぞれ、それっぽい名前.cとして存在しているのですが、nilについてはどうやらそうではない模様。

GitHub - ruby/ruby: The Ruby Programming Language

仕方がないので頑張って探してみましょう。

おもむろに git grep nil

rubyリポジトリをgit cloneしてきて*1、おもむろに git grep nil。当たり前だけど普通にnilばっか出てきてダメですね;;

よく考えればnilはクラスではないのでクラス名で検索しないとダメだろう。というわけでNilClassを調べます。念のため書いておきますが、nilのクラスは以下のようにして調べることができますよ。

irb(main):001:0> nil.class
=> NilClass

気を取り直して、おもむろにgit grep NilClass。これでも結構たくさんの結果が出てきてしまいました。ここから目grepするだけでも目的のものはわかるのですが、もうちょっと楽をするために.cのみで検索してみましょう。

% git grep NilClass -- "*.c"
class.c:    SPECIAL_SINGLETON(Qnil, rb_cNilClass);
class.c: *       NilClass, TrueClass and FalseClass.
complex.c:    rb_define_method(rb_cNilClass, "to_c", nilclass_to_c, 0);
ext/json/generator/generator.c:             mTrueClass, mFalseClass, mNilClass, eGeneratorError,
ext/json/generator/generator.c:static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self)
ext/json/generator/generator.c:    mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
ext/json/generator/generator.c:    rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
object.c:VALUE rb_cNilClass; /*!< NilClass class */
object.c: *  <code>false</code>, it returns NilClass, TrueClass, or FalseClass,
object.c: *     nil.singleton_class         #=> NilClass
object.c: * Document-class: NilClass
object.c:    rb_cNilClass = rb_define_class("NilClass", rb_cObject);
object.c:    rb_define_method(rb_cNilClass, "to_i", nil_to_i, 0);
object.c:    rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0);
object.c:    rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0);
object.c:    rb_define_method(rb_cNilClass, "to_a", nil_to_a, 0);
object.c:    rb_define_method(rb_cNilClass, "to_h", nil_to_h, 0);
object.c:    rb_define_method(rb_cNilClass, "inspect", nil_inspect, 0);
object.c:    rb_define_method(rb_cNilClass, "&", false_and, 1);
object.c:    rb_define_method(rb_cNilClass, "|", false_or, 1);
object.c:    rb_define_method(rb_cNilClass, "^", false_xor, 1);
object.c:    rb_define_method(rb_cNilClass, "===", rb_equal, 1);
object.c:    rb_define_method(rb_cNilClass, "nil?", rb_true, 0);
object.c:    rb_undef_alloc_func(rb_cNilClass);
object.c:    rb_undef_method(CLASS_OF(rb_cNilClass), "new");
rational.c:    rb_define_method(rb_cNilClass, "to_r", nilclass_to_r, 0);
rational.c:    rb_define_method(rb_cNilClass, "rationalize", nilclass_rationalize, -1);
spec/ruby/optional/capi/ext/constants_spec.c:static VALUE constants_spec_rb_cNilClass(VALUE self) {
spec/ruby/optional/capi/ext/constants_spec.c:  return rb_cNilClass;
spec/ruby/optional/capi/ext/constants_spec.c:  rb_define_method(cls, "rb_cNilClass", constants_spec_rb_cNilClass, 0);
sprintf.c:      if (value == rb_cNilClass) {
vm.c:    if (klass == rb_cNilClass) return NIL_REDEFINED_OP_FLAG;
vm.c:          C(NilClass), C(TrueClass), C(FalseClass));

かなり人間がわかるような量になりました。 これで必要な情報はほぼわかったようなものですが、実装はobject.cにあるようです。

object.c 👀

もはや説明不要なレベルですが、先ほどの結果を抜粋すると、object.cのここら辺が見るべきポイントのようですね。

object.c:    rb_cNilClass = rb_define_class("NilClass", rb_cObject);
object.c:    rb_define_method(rb_cNilClass, "to_i", nil_to_i, 0);
object.c:    rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0);
object.c:    rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0);
object.c:    rb_define_method(rb_cNilClass, "to_a", nil_to_a, 0);
object.c:    rb_define_method(rb_cNilClass, "to_h", nil_to_h, 0);
object.c:    rb_define_method(rb_cNilClass, "inspect", nil_inspect, 0);
object.c:    rb_define_method(rb_cNilClass, "&", false_and, 1);
object.c:    rb_define_method(rb_cNilClass, "|", false_or, 1);
object.c:    rb_define_method(rb_cNilClass, "^", false_xor, 1);
object.c:    rb_define_method(rb_cNilClass, "===", rb_equal, 1);
object.c:    rb_define_method(rb_cNilClass, "nil?", rb_true, 0);

あまりCの実装には詳しくありませんが、少なくともrb_define_class でNillClassを定義していて、rb_define_method(rb_cNilClass, ...) でメソッド名と実装の紐付けを行なっていることがわかります。 例えば、to_inil_to_iで実装されているようですね。このnil_to_iも同じobject.cで実装されているのでみてみましょう。

static VALUE
nil_to_i(VALUE obj)
{
    return INT2FIX(0);
}

こんな感じでゼロを返すという強い意志を感じます。

というわけで、NilClassの実装を見ることができました。まあ今回のポイントはどのファイルで実装されているのか?というのを調べる部分で、それはobject.cでした、ということですね。

合わせて読みたい

あんまり関係ないけどこちらもよろしくお願いします

改訂2版 パーフェクトRuby

改訂2版 パーフェクトRuby

*1:実際はruby/rubyghqで手元に取得済みなのであった

「あなたの知らないセキュリティの非常識」を読んだ

辻伸弘さんから、「あなたのセキュリティ」シリーズ第一弾(http://sugamasao.hatenablog.com/entry/2016/10/31/083124)に続いて頂きました! (本当は12月中にこのエントリを書くつもりだったのですが遅くなってしまった……)

今回の内容も実際に発生したセキュリティインシデントに対して対策や対応方法について書いてあります。 が、なかなか事例が生々しい例が多いということもあって身が引き締まる思いです。

あなたの知らないセキュリティの非常識

あなたの知らないセキュリティの非常識

気になった内容メモ

ランサムウェアにお金を払うか?

バックアップから人質に取る事例。昨年はよく話題に上がった事例だと思います。 とにかく恐ろしい。

個人の端末ではなく、サーバにアクセスして復旧手段を封じてから本丸を暗号化させて身代金要求するようなケースの紹介があるのですが、暗号化や侵入の手順の説明だけではなく、被害にあった業者と攻撃者が交渉して代金の支払いやデータの復旧が行われたという事例の紹介になっていて、読んでいるだけで胃が痛くなる。 こんなんやられたら死ぬわ、、、。

また、脅迫型のDDos攻撃の事例も紹介されている。 これは言ってしまえばDDos攻撃されたくなかったら金を払えということなのだけど、脅迫メールとともにお試しで攻撃してブラフでないことを証明したり攻撃方法としてMiraiボットネットを使用するなどが書かれていたらしい。

Miraiボットネットについてよく知らなかったのだけど、Iot機器に感染させて様々な機器からDDos攻撃を仕掛けるとか言われるの怖すぎますね……。単にIPアドレスで弾くみたいなことはできないでしょうし。 参考 : http://techfactory.itmedia.co.jp/tf/articles/1704/13/news010.html

他にも、筆者がアノニマスのアカウントから人物像をプロファイリングしている話や、Webサイトを改ざんしたハッカーに直接コンタクトを取ってみたりする話が載っているのですが、スリリングで面白いというか、すげえって感じですね。

攻撃の被害者になったら

この章は実際に筆者の会社で被害にあった時の対応などが書かれている。最高の知見では???

実際の対応について、三つのポイントというのが書いてあって、例えば対応の意思決定者として社長が参画しているとか、きちんと情報を公開するという方針をとったなど。

これはぜひ本書を手にとって読んでみてもらいたい。

本作の見どころ(難易度:高)

前作の「あなたのセキュリティ対策間違ってます」で、Amazonのレビューに著者である辻さんのお母さんがレビューを書いていたことがありました。 非常に良い内容で一部界隈では盛り上がったのですが、なんらかの事情でAmazonから消えてしました(親族からのレビューはダメとかあるのかな?)。

そのレビューの文章が本作には載っているので、もし見逃してしまった人は一見の価値ありです。

合わせて読みたい

前作の「あなたのセキュリティ対策間違ってます」はこちらからどうぞ

あなたのセキュリティ対応間違っています

あなたのセキュリティ対応間違っています

High Sierra上にPallarels DesktopでHigh Sierraの仮想環境を構築する

うまくインストールできなくて困った

この時はPallarels Desktop 13.1.0を使っていた

それからしばらくして

気を取り直してリベンジしたもののうまくできない・・・

のだが、Pallarels Deskotop 13.1.1がリリースされていることに気がついたのでアップデートしてから再チャレンジ。

できた

めっちゃわかりにくいと思うけど仮想環境上のHighSierraです

f:id:seiunsky:20171024203814p:plain

バージョン情報と手順

f:id:seiunsky:20171024203440p:plain

手順は特に何もないのだけど、記憶を失った時のために書いておくと、仮想環境の新規インストールから「インストール」の「回復パーティションを使用」からOSのイメージを使ってインストールする。

f:id:seiunsky:20171024203451p:plain

わかばちゃんと学ぶ Git使い方入門を読んだ

読みました

わかばちゃんと学ぶ Git使い方入門

わかばちゃんと学ぶ Git使い方入門

目次

  • CHAPTER 1 Gitって何?
  • CHAPTER 2 個人でGitを使ってみよう
  • CHAPTER 3 複数人でGitを使ってみよう
  • CHAPTER 4 実用Git 〜 こんなときはどうすればいい?
  • CHAPTER 5 Gitで広がる世界

読むモチベーション

普段から仕事などでgitは使っているので、今さらgitとは?のような話を学ぼうと思ったわけではなくて、本書の目次のCHAPTER 4「実用Git 〜 こんなときはどうすればいい?」が目当てでした。

というのも、基本的には必要に迫られて色々なコマンドを覚えてきたので体系的な(というか詳しい人の)「こういう時はこうする」という方法が果たして自分の普段やっていることと合っているのだろうか?という不安があったんですね。

結論から書くと

自分が普段やっていたのと同じことが本書に書かれていたので間違ってなかったんだなwと安心できてよかったし、説明がとてもわかりやすくてよかった。

読んだメモ

  • ブランチやリモートとローカルの関係などが図示されているのはとてもわかりやすい
  • コンフリクトやrebaseなども丁寧に説明されているのは非常によかった
  • 説明は基本的にSourceTreeの画面で行われるので、SourceTreeユーザはドンピシャでわかって良さそう
    • 普段CLIでしかやらないので馴染みはなかったけど普段使っているコマンドの知識があるので問題なく読めた
    • 逆にいうと、完全に知識がない状態でCLIベースで学ぼうとするにはちょっと頑張る必要があるかも
  • コラムでGitHub Flowの説明はあるけど、基本的にはブランチを使ったリリースフローなどの説明はなくて、あくまでブランチ自体の使い方などにとどめてある。のでそっち方面は別の書籍などで補完すると良さそう

日頃使っている人はともかく、VSC関連のツールを使ったことないけどgit使ってみたい人とか、gitをたまにしか使わなくて慣れていない人などが読むには非常に良いと思う。 使い始めた時に疑問に思うようなことはきちんとわかばちゃんが疑問に思う→説明→実演という流れで解決していくので、怖くて実行できない、みたいな恐怖心はだいぶ和らぐんじゃあないかな。

新人研修などでgitをゼロから教える場面があったらこの本渡せば良いんじゃないかと思うのでおすすめです(たぶん)。

読む用、保管用、布教用で3冊購入すると良さそうです。

わかばちゃんと学ぶ Git使い方入門

わかばちゃんと学ぶ Git使い方入門

Ruby2.4のoptparseでHashにパース結果をマッピングするintoという便利オプションを調べた

表題の通りなんですが

blog.cognitohq.com

上記のページの「Parse CLI options into a Hash」の項目を見ると、以下のように parse メソッドに :into でハッシュオブジェクトを渡すと自動でマッピングしてくれるという地味に便利な機能が追加された。

上記のURLから抜粋

require 'optparse'
require 'optparse/date'
require 'optparse/uri'

cli =
  OptionParser.new do |options|
    options.define '--from=DATE',    Date
    options.define '--url=ENDPOINT', URI
    options.define '--names=LIST',   Array
  end

config = {}

args = %w[
  --from  2016-02-03
  --url   https://blog.blockscore.com/
  --names John,Daniel,Delmer
]

cli.parse(args, into: config)

config.keys    # => [:from, :url, :names]
config[:from]  # => #<Date: 2016-02-03 ((2457422j,0s,0n),+0s,2299161j)>
config[:url]   # => #<URI::HTTPS https://blog.blockscore.com/>
config[:names] # => ["John", "Daniel", "Delmer"]

:into で便利になるのはわかるものの、このサンプルを見ると define って何だろう、とか短いオプション名(-uとか)も指定した場合どうなるの?ってところが色々と疑問だったので調べてみた。

define is 何

情弱なのでリファレンスマニュアルに載ってないAPIだから define を使ったオプションの定義したことがなかった(実は載っているのかと思ってドキドキしたけどやっぱり載ってない)。

library optparse (Ruby 2.4.0)

というわけでRubyのソースを確認して見るとこんな感じ

https://github.com/ruby/ruby/blob/v2_4_2/lib/optparse.rb#L1465-L1505

抜粋すると以下のように、いつも使っている on メソッドが内部で呼び出しているメソッドなんですね。

  def define(*opts, &block)
    top.append(*(sw = make_switch(opts, block)))
    sw[0]
  end

  def on(*opts, &block)
    define(*opts, &block)
    self
  end

ソース内の雰囲気からすると、 on は公開用で define は内部で使う用っぽい気がするけど*1、普通に呼び出せるしどっちでも良いのかもしれない。まあ、今まで通り on 系を使えば良いかなって気がしますね……。

オプション名 is 何

割り当てるオプション名ってどう決まるのか。

options.on '-a, '--argument=VAL'

みたいに定義した時にどっちが使われるのかなという話でもありますし、オプション名に - が含まれていた場合どうなるのか(ネタバレすると:"foo-bar"みたいになる)など疑問が湧きますよね。

これを知るにはざっくり :into オプションの流れを追う必要があるのですが、結論を先に書いておくと

  • 短いオプション名と長いオプション名があった場合長いオプション名が使用される
  • オプション名の先頭ハイフンを取り除いた文字列を .to_sym した値になる

という動作のようです。

プログラム的には

という流れのようですね。

まとめ

    OptionParser.new do |options|
      options.on '-r', '--ruby=VAL' do |val|
        val.downcase
      end
      options.on '-p', '--perl=VAL' do |val|
        val.upcase
      end
      options.on '-g', '--go-lang' do
        'go'
      end
      options.on '-d' do
        true
      end
      options.on_tail '-h', '--help', 'hi'
    end

こんな定義をした場合、 into オプションでHashを渡した場合は

  {
      ruby: 'ruby',
      perl: 'PERL',
      'go-lang': 'go',
      d: true
  }

こんな値が得られます。便利ですね。

サンプルソースコードとテストケースは以下にあります(主に test/unit を使ってみたかっただけw)。 https://github.com/sugamasao/optparser_ruby24_into_sample

*1:実際のところはどうなんでしょうか?

3DS LLがWifiを見つけられなくなった(解決済み→ではなかった)

ある日気がつくとインターネットに繋がらなくなった

我が家の環境は以下のような流れで接続している(細かくいうともうちょっとあるけど)

  1. 各機器
  2. AirMac (https://www.apple.com/jp/airmac-express/)
  3. インターネット

そして、他の機器は問題なく接続できているにも関わらず、3DSだけ、ある日突然繋がらなくなった。

具体的にいうと、アクセスポイントを見つけることが不可能になってしまい、結果としてインターネットに繋がらなくなった。

2年くらい前にも同じ現象が発生したが、気がついたら解消していた。だがしかし、また発生してしまった。普段インターネットに接続することはないけど、ゲームを購入するときにダウンロードで購入できないのは困る。

具体的には👇の発売日までにはどうにかする必要があって、すわ修理や買い替えが必要か!と思ったけど、自力で解決できた。

shin-megamitensei.jp

対応方法

まず、Wifi側の再起動や3DS本体の再起動、3DSについてるWifiのスイッチなどは何度かON/OFFを試したが効果はなかった。 何度やっても「アクセスポイントが見つかりませんでした」と表示される。

3DS側のインターネット接続を見直す

3DSのインターネット接続で、新規登録→アクセスポイントを検索でも上記と同じ結果。 その他、手動でSSIDやセキュリティを入力する方式で試してもアクセスポイントが見つからない状態は変わらない*1

必死にググっていたところ、検索結果のうちの一つに、接続先の詳細設定でIPアドレスなどを手動で入力すると繋がったという情報が載っていたのを発見した。 モノは試しということで、 IPアドレスDSN を手動で設定したところ、無事にインターネットに繋がるようになった。

なぜ自動取得だとうまくいかないのかはよくわからないのだけど、ハード的にWifi部分がぶっ壊れているとかではなくてよかった。

設定メモ

繋がるようになった3DSのネットワーク設定をメモしておく

繋がるようになったことで、ファイアーエムブレム Echoesの無料コンテンツが届いていることに気がつけてとてもお得でした。

追記:なんか明らかに繋がっていたのだが、数分後にはアクセスポイントが見つかりません状態に戻ってしまった。あれは一体何だったんだ……

*1:ここまでは今まで何度も試したが解決しなかった

エラスティックリーダーシップを読んだ

読んだと言うかもちろん読んだのですが訳者の島田( @snoozer05 )さんからご恵贈いただきました(ありがとうございます!!)。

エラスティックリーダーシップ ―自己組織化チームの育て方

エラスティックリーダーシップ ―自己組織化チームの育て方

ちょっとずつ読み進めていましたが、先日、ようやく読み終えました*1

あまりリーダー向けの本などを読んだことがなったので、なんとなく「こうやったほうが良さそうだなぁ」と雰囲気で思っていたことに対して名前がつけられていたり、かなり具体的に書かれているのがとてもよかった*2

以下は印象に残った部分について簡単に書いた内容です。

6章 コミットメント言語

章自体の趣旨としては、章のタイトル通りミーティングなどでこれからやることを決めた際に、タスクとしては上がっているにも関わらず「なる早で対応します〜」のような期日や成果に対してふんわりとした言い方をせずに、具体的な言い方をしましょうという話です。

コミットメント言語でやることを明確にしましょうと言われれば「そりゃそうだ」と思う反面、予定外のものや想定以上の問題があったりして簡単にコミットできないよねというのもまた事実ですよね。ではどうすれば良いのか?ということが具体的に述べられていて、例えば、「来週中にバグを直します」ではなく、「来週は毎日5時間バグを修正するために使います」のように、自分が制御できる内容に落とし込んでコミットしましょうということが書いてあって、とてもよかった。

何が良いって、これ、上っ面だけ読んで「〜します」と言わせるようにした結果「なんでできないんだ」とならないように現実に即している内容が書いてあるのが良いです。

8章 クリアリングミーティング

恥ずかしながらこのような言葉を知らなかった。 本文中の定義を引用すると、以下のようなこと(本ではもっと詳しく書いてあるよ!)。

クリアリングミーティグと呼ぶ理由は、うまくいっていないこと、仕事についてしまいこんでいる悪い感情、共有すべき情報など、チームが知っていること全てを明らか(クリア)にするからだ。そして、それに対処する。

具体的にどういうことをやり取りするかはぜひ本書を手に取ってもらうとして、うまくいっていないことを引き出し方や話を終わらせるポイントなどが載っていて、やっぱりこれも単にやり方だけあって「ギスギスしちゃう・・・」みたいにならないようなケアがされてるのがとても良い。

そのほか

後半の第4部、第5部は色々な人のリーダーシップに関するエッセイになっているのだけど、第5部は国内の著名なエンジニアによるエッセイになっている。国内のエンジニアのエッセイになるとグッと身近な感じが*3してきて、刺激的だったりする。

総じて、あまり知らなかったり、自分の中で明文化されていないような考え方が非常に具体的に*4載っているのがよかったと思う。 多分、ふだんチームメンバーを抱えているリーダーだけではなく、ミーティングでファリシテーションするような人とかが読んでも有用だと思う。もちろん、メンバーという立場でも自分から発言する形を見直していくというのもすごく良いと思う。

とにかく、語彙がなくて良かったしか書けないけどこういう内容はなかなか見ない種類の本だったのでとにかくよかった。

エラスティックリーダーシップ ―自己組織化チームの育て方

エラスティックリーダーシップ ―自己組織化チームの育て方

どうしても書かなくてはいけない宣伝

先日発売した改訂2版パーフェクトRubyですが、なんとKindle版も発売しているのでよろしくお願いいたします(下の方がkindle版です)。

改訂2版 パーフェクトRuby

改訂2版 パーフェクトRuby

改訂2版 パーフェクトRuby

改訂2版 パーフェクトRuby

今回はちゃんとリフロー型になっているので、お使いのデバイスでもおよそ見やすい形になっていると思います。 もちろん、gihyo.jpからであればEPUB/PDFのどちらも購入することが可能です。

gihyo.jp

*1:せっかく頂いたのにブログに書くの遅くなってしまってスミマセン

*2:単に自分が不勉強なだけの可能性もある……

*3:勝手にそう思ってるだけです

*4:ここでいう具体的とは単なる方法論だけではなく、感情に配慮した内容が