2022/08/25 今回の気になった bugs.ruby のチケット
今週は lazy.take(0)
した時に期待した挙動にならないというバグ報告がありました。
[Bug #18972] String#byteslice should return BINARY (aka ASCII-8BIT) Strings
# 今はレシーバのエンコーディングになっている p "fée".byteslice(1).encoding # => #<Encoding:UTF-8> p "fée".byteslice(1).valid_encoding? # => false
- 期待する挙動は以下の通り
p "fée".byteslice(1).encoding # => #<Encoding:ASCII-8BIT> p "fée".byteslice(1).valid_encoding? # => true
[Bug #18971] Enumerator::Lazy.take(0) leaks first element into next operation
- 以下のように
lazy
でtake(0)
を使用した時は期待する挙動になる
(2..10).take(0).to_a # => [] (2..10).take(0).map(:&itself).to_a # => [] (2..10).lazy.take(0).to_a # => []
- しかし、以下のように
take(0)
した後に別の操作をすると期待する挙動にならないというバグ報告
p (2..10).lazy.take(0).map(&:itself).to_a # => [2] p (2..10).lazy.take(0).select(&:even?).to_a # => [2] p (2..10).lazy.take(0).select(&:odd?).to_a # => [] p (2..10).lazy.take(0).reject(&:even?).to_a # => [] p (2..10).lazy.take(0).reject(&:odd?).to_a # => [2] p (2..10).lazy.take(0).take(1).to_a # => [2] p (2..10).lazy.take(0).take(0).take(1).to_a # => [2] p (2..10).lazy.take(0).drop(0).to_a # => [2] p (2..10).lazy.take(0).find_all {|_| true}.to_a # => [2] p (2..10).lazy.take(0).zip((12..20)).to_a # => [[2, 12]] p (2..10).lazy.take(0).uniq.to_a # => [2] p (2..10).lazy.take(0).sort.to_a # => [] p (2..2).lazy.take(0).sort.to_a # => []
[Bug #18974] Wrong line number in the rescue iseq for the exception matching code
iseq
の出力とrescue => e
している箇所の行番号がズレているというバグ報告- コード上は4行目になっているが iseq の出力では5行目になっている
def foo begin raise 'error' rescue => e puts e.message end end puts RubyVM::InstructionSequence.of(method :foo).disasm __END__ == disasm: #<ISeq:foo@/tmp/vL5efqT/19:1 (1,0)-(7,3)> (catch: TRUE) == catch table | catch type: rescue st: 0000 ed: 0005 sp: 0000 cont: 0006 | == disasm: #<ISeq:rescue in foo@/tmp/vL5efqT/19:4 (4,2)-(5,18)> (catch: TRUE) | local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) | [ 1] $!@0 | 0000 getlocal_WC_0 $!@0 ( 5)[Li] | 0002 putobject StandardError | 0004 checkmatch 3 | 0006 branchunless 20 | 0008 getlocal_WC_0 $!@0 ( 4) | 0010 setlocal_WC_1 e@0 | 0012 putself ( 5) | 0013 getlocal_WC_1 e@0 | 0015 opt_send_without_block <calldata!mid:message, argc:0, ARGS_SIMPLE> | 0017 opt_send_without_block <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE> | 0019 leave | 0020 getlocal_WC_0 $!@0 | 0022 throw 0 | catch type: retry st: 0005 ed: 0006 sp: 0000 cont: 0000 |------------------------------------------------------------------------ local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] e@0 0000 putself ( 3)[LiCa] 0001 putstring "error" 0003 opt_send_without_block <calldata!mid:raise, argc:1, FCALL|ARGS_SIMPLE> 0005 nop ( 1) 0006 leave ( 7)[Re]
[Feature #18408] Allow pattern match to set instance variables
# これはエラーになる case {name: "John", age: 42} in name: /jo/ => @name, age: @age end puts [@name, @age] #=> ["John", 42]
- 上記のようにインスタンス変数でも束縛したいことがチケットの内容になる
- これに関しては以前から議論されていたんですが現時点では『ローカル変数以外はサポートしない』という意思決定がされたようです
- https://bugs.ruby-lang.org/issues/18408#note-19
42 => @a
を許容すると42 => a[1]
や42 => obj.attr
などより複雑な要求がくる事が理由として上げられていました