55323


**質問に至った背景**

Rubyで入力された数の範囲の素数をもれなく求める関数を書いているのですが,なぜか不要な`end`キーワードを求められます.この`end`がどこの区切りかわからなかったので質問させていただきました.なお私個人としてはirb(下記ログ参照)でいう33行目の`end`は`コード中のendを要求する命令はすべてendで閉じられているため不要`だと考えています.

**問題のコード**  
このコードは入力された数の範囲の素数を`エラトステネスのふるい`ではじき出す関数のみを定義してます.

[code]

    #!/usr/bin/env ruby
    
    def sieve(num);
    
          n = num;
          array_seed = [];
    
          while n > 1 do
       　　　　　array_seed << n;
    　　　   　　n -= 1;
          end
    
          array_seed.reverse!;
          primes = [];
    
          while true do
    　　　   　　array_seed_tmp = array_seed.shift;
    　　　　　   primes << array_seed;
    
               break if !array_seed_tmp
    
               trashnum = [];
    
               array_seed.each do |x|
                   trashnum << x; if x % array_seed_tmp == 0
               end
             primes -= trashnum
    　    end
          array_string = primes.to_s;
          array_string.each do |y|
             print("#{y}\s");
          end
        end
    end
    
[/code]

これの場合`irb`のチェックが通ります.

[code]

    psieve.rb(main):001:0> #!/usr/bin/env ruby
    => nil
    psieve.rb(main):002:0> 
    psieve.rb(main):003:0> def sieve(num);
    psieve.rb(main):004:1>   
    psieve.rb(main):005:1>       n = num;
    psieve.rb(main):006:1>       array_seed = [];
    psieve.rb(main):007:1> 
    psieve.rb(main):008:1>       while n > 1 do
    psieve.rb(main):009:2*    　　　　　array_seed << n;
    psieve.rb(main):010:2> 　　　   　　n -= 1;
    psieve.rb(main):011:2>       end
    psieve.rb(main):012:1> 
    psieve.rb(main):013:1>       array_seed.reverse!;
    psieve.rb(main):014:1>       primes = [];
    psieve.rb(main):015:1> 
    psieve.rb(main):016:1>       while true do
    psieve.rb(main):017:2* 　　　   　　array_seed_tmp = array_seed.shift;
    psieve.rb(main):018:2> 　　　　　   primes << array_seed;
    psieve.rb(main):019:2>          
    psieve.rb(main):020:2>            break if !array_seed_tmp
    psieve.rb(main):021:2>         
    psieve.rb(main):022:2>            trashnum = [];
    psieve.rb(main):023:2> 
    psieve.rb(main):024:2>            array_seed.each do |x|
    psieve.rb(main):025:3*                trashnum << x; if x % array_seed_tmp == 0
    psieve.rb(main):026:4>            end
    psieve.rb(main):027:3>          primes -= trashnum
    psieve.rb(main):028:3> 　    end
    psieve.rb(main):029:2>       array_string = primes.to_s;
    psieve.rb(main):030:2>       array_string.each do |y|
    psieve.rb(main):031:3*          print("#{y}\s");
    psieve.rb(main):032:3>       end
    psieve.rb(main):033:2>     end
    psieve.rb(main):034:1> end
    => :sieve
    psieve.rb(main):035:0> 
    psieve.rb(main):036:0> 
    
[/code]

しかし33行目(下から4番目)の`end`を無効にすると構文エラーが起こり出処不明の`end`を要求されます.

[code]

    #!/usr/bin/env ruby
    
    def sieve(num);
    
          n = num;
          array_seed = [];
    
          while n > 1 do
       　　　　　array_seed << n;
    　　　   　　n -= 1;
          end
    
          array_seed.reverse!;
          primes = [];
    
          while true do
    　　　   　　array_seed_tmp = array_seed.shift;
    　　　　　   primes << array_seed;
    
               break if !array_seed_tmp
    
               trashnum = [];
    
               array_seed.each do |x|
                   trashnum << x; if x % array_seed_tmp == 0
               end
             primes -= trashnum
    　    end
          array_string = primes.to_s;
          array_string.each do |y|
             print("#{y}\s");
          end
        #end
    end
    
[/code]

[code]

    psieve.rb(main):001:0> #!/usr/bin/env ruby
    => nil
    psieve.rb(main):002:0> 
    psieve.rb(main):003:0> def sieve(num);
    psieve.rb(main):004:1>   
    psieve.rb(main):005:1>       n = num;
    psieve.rb(main):006:1>       array_seed = [];
    psieve.rb(main):007:1> 
    psieve.rb(main):008:1>       while n > 1 do
    psieve.rb(main):009:2*    　　　　　array_seed << n;
    psieve.rb(main):010:2> 　　　   　　n -= 1;
    psieve.rb(main):011:2>       end
    psieve.rb(main):012:1> 
    psieve.rb(main):013:1>       array_seed.reverse!;
    psieve.rb(main):014:1>       primes = [];
    psieve.rb(main):015:1> 
    psieve.rb(main):016:1>       while true do
    psieve.rb(main):017:2* 　　　   　　array_seed_tmp = array_seed.shift;
    psieve.rb(main):018:2> 　　　　　   primes << array_seed;
    psieve.rb(main):019:2>          
    psieve.rb(main):020:2>            break if !array_seed_tmp
    psieve.rb(main):021:2>         
    psieve.rb(main):022:2>            trashnum = [];
    psieve.rb(main):023:2> 
    psieve.rb(main):024:2>            array_seed.each do |x|
    psieve.rb(main):025:3*                trashnum << x; if x % array_seed_tmp == 0
    psieve.rb(main):026:4>            end
    psieve.rb(main):027:3>          primes -= trashnum
    psieve.rb(main):028:3> 　    end
    psieve.rb(main):029:2>       array_string = primes.to_s;
    psieve.rb(main):030:2>       array_string.each do |y|
    psieve.rb(main):031:3*          print("#{y}\s");
    psieve.rb(main):032:3>       end
    psieve.rb(main):033:2>     #end
    psieve.rb(main):034:2> end
    psieve.rb(main):035:1> 
    psieve.rb(main):036:1> 
    SyntaxError (psieve.rb:35: syntax error, unexpected end-of-input, expecting end)
        from /usr/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
        from /usr/bin/irb:23:in `load'
        from /usr/bin/irb:23:in `<main>'
    
[/code]

**推測**  
何度も再起動したりRubyを入れ直したりしてみましたがエラーは解決されなかったのでおそらく処理系のエラーバグとは考えにくいので,自分がどこかで書き損じているのだと思います(元々はFedoraでこのような構文解析エラーに遭遇しましたが,緊急用のArchLabsでも同様のエラーが出たので)

伺いたいことを纏めると,

  * 33行目のendはどこのendなのか?

ということです.

最後になりましたが,OSはFedora30とArchLabs(最新版)でRubyのバージョンが共に2.6.3です.


CC BY-SA 4.0
2019-05-29T00:40:07.567
55321
2019-05-29T01:06:47.647
2019-05-29T01:06:47.647
19110
30493
question
ruby
なぜか必要のないendを要求される


質問に記載のサンプルには全角空白がありますがわざとですよね？

とりあえず、25行目のIFに対応するendが無いものと思われます。  
`ruby-beautify`をかけたものが下記になります。

[code]

    #!/usr/bin/env ruby
    
    def sieve(num)
    
            n = num;
            array_seed = [];
    
            while n > 1 do
                    array_seed << n;
                    n -= 1;
            end
    
            array_seed.reverse!;
            primes = [];
    
            while true do
                    array_seed_tmp = array_seed.shift;
                    primes << array_seed;
    
                    break if !array_seed_tmp
    
                    trashnum = [];
    
                    array_seed.each do |x| trashnum << x;
                            if x % array_seed_tmp == 0
                            end
                            primes -= trashnum
                    end
                    array_string = primes.to_s;
                    array_string.each do |y|
                            print("#{y}\s");
                    end
            end
    end
    
[/code]


CC BY-SA 4.0
2019-05-29T01:01:29.363
55323
2019-05-29T01:01:29.363
7676
55321
answer