0

Crystalコンパイラのソースコードで、そのようなコードを見たことがあります

def dirname
  filename = @filename
  if filename.is_a?(String)
    File.dirname(filename)
  else
    nil
  end
end

def original_filename
  case filename = @filename
  when String
    filename
  when VirtualFile
    filename.expanded_location.try &.original_filename
  else
    nil
  end
end

def <=>(other)
  self_file = @filename
  other_file = other.filename
  if self_file.is_a?(String) && other_file.is_a?(String) && self_file == other_file
    {@line_number, @column_number} <=> {other.line_number, other.column_number}
  else
    nil
  end
end

では、インスタンス変数を直接使用する代わりに、インスタンス変数をローカル変数に割り当てる理由は何でしょうか?

4

1 に答える 1

4

@filename は、nil でないかどうか (@filename の場合) をチェックしてからアクセスするまでの間に同時に変更される可能性があるためです。Crystal はコンパイルされたプログラムであり、@filename が期待されるタイプではない場合、プログラムは segfault でクラッシュします。

ローカル変数に代入することで、変数が存在することを確認します。

于 2015-09-17T19:35:31.390 に答える