Issue #17405 has been updated by osyo (manga osyo).


hi.

This error is caused by [calling `Reline::Unicode.calculate_width` in `irb`](https://github.com/ruby/irb/blob/ae91f7ac13a97e2ce8bc7524aea279e797a3ba27/lib/irb.rb#L784).
`Reline::Unicode.calculate_width` should be initialized with [`#may_req_ambiguous_char_width`](https://github.com/ruby/reline/blob/2992ac02ae2329cc8af00c8304d0dc60aad74f94/lib/reline.rb#L363-L377) inside Reline.
However, in the case of `--nomultiline`, `#may_req_ambiguous_char_width` is not called and is not initialized because Reline is not used.
This was causing the call to `Reline::Unicode.calculate_width` to fail, resulting in an error.
This problem has been solved by explicitly calling `#may_req_ambiguous_char_width` inside `Reline::Unicode.calculate_width`.

PR is merged : https://github.com/ruby/reline/pull/224


----------------------------------------
Bug #17405: irb ---nomultiline gets exception when output contains some non-ascii characters
https://bugs.ruby-lang.org/issues/17405#change-89417

* Author: rsharman (Richard Sharman)
* Status: Open
* Priority: Normal
* Assignee: aycabta (aycabta .)
* ruby -v: ruby 3.0.0dev (2020-12-21T02:23:01Z master ac78d90d5e) [x86_64-darwin18]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
When irb is called with the --nomultiline option (for example, when called from emacs), then if the output contains some special characters (such as the square root sign, or a single quotation mark), then irb gets an exception.

Without the --multiline option the problem does not happen.  

Here is an example with a string assignment to variable m.

Without fix:  Without --nomultiline there is no problem:

henry:tmp richard$ irb
irb(main):001:0> source 'test.rb'
test.rb(main):002:0> # coding: utf-8
=> nil
test.rb(main):003:0> m = "ĘŚ10"
=> "ĘŚ10"
test.rb(main):004:0> m
=> "ĘŚ10"
=> nil

But with --nomultiline irb gets an exception (but the assignment did work):

henry:tmp richard$ irb --nomultiline
irb(main):001:0> source 'test.rb'
test.rb(main):002:0> # coding: utf-8
=> nil
test.rb(main):003:0> m = "ĘŚ10"
Traceback (most recent call last):
        8: from /Users/richard/.rbenv/versions/2.7.2/bin/irb:23:in `<main>'
        7: from /Users/richard/.rbenv/versions/2.7.2/bin/irb:23:in `load'
        6: from /Users/richard/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
        5: from (irb):1
        4: from /Users/richard/.rbenv/versions/2.7.2/lib/ruby/2.7.0/reline/unicode.rb:99:in `calculate_width'
        3: from /Users/richard/.rbenv/versions/2.7.2/lib/ruby/2.7.0/reline/unicode.rb:99:in `scan'
        2: from /Users/richard/.rbenv/versions/2.7.2/lib/ruby/2.7.0/reline/unicode.rb:108:in `block in calculate_width'
        1: from /Users/richard/.rbenv/versions/2.7.2/lib/ruby/2.7.0/reline/unicode.rb:108:in `+'
TypeError (nil can't be coerced into Integer)
test.rb(main):004:0> m
=> "ĘŚ10"
=> nil




The problem is that in method get_mbchar_width of class Reline::Unicode Reline.ambiguous_width can have a nil value, whereas the code seems to expect a low integer (unicode.rb line 84).  This causes method calculate_width to add a nil value to width (line 109).

I don°«t know what value Reline.ambiguous_width should be in these cases;  the simple change below uses a value of 1 to avoid the exception:

```
bash-5.1$ diff unicode.rb{.orig,}
84c84,85
<       Reline.ambiguous_width
---
>       width = Reline.ambiguous_width
>       width.nil? ? 1 : width  # if nil then assume 1
bash-5.1$

```
```
```


With above fix:

henry:tmp richard$ irb --nomultiline
irb(main):001:0> source 'test.rb'
test.rb(main):002:0> # coding: utf-8
=> nil
test.rb(main):003:0> m = "ĘŚ10"
=> "ĘŚ10"
test.rb(main):004:0> m
=> "ĘŚ10"
=> nil
henry:tmp richard$ 


---Files--------------------------------
test.rb (30 Bytes)
Patch (456 Bytes)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>