質問

このコードを使用して、ユーザーが名前を入力できるようにし、プログラムは空の文字列を入力するまでそれらを配列に保存します (名前を入力するたびに Enter キーを押す必要があります)。

people = []
info = 'a' # must fill variable with something, otherwise loop won't execute

while not info.empty?
    info = gets.chomp
    people += [Person.new(info)] if not info.empty?
end

このコードは、実行するとより見栄えがよくなります...while ループ:

people = []

do
    info = gets.chomp
    people += [Person.new(info)] if not info.empty?
while not info.empty?

このコードでは、ランダムな文字列に情報を割り当てる必要はありません。

残念ながら、このタイプのループは Ruby には存在しないようです。誰かこれを行うより良い方法を提案できますか?

役に立ちましたか?

解決

注意

開始< code> < condition> がRubyの作者Matzによって拒否されている間に終了します。代わりに、彼は Kernel#loop の使用を提案します。例えば、

loop do 
  # some code here
  break if <condition>
end 

メール交換 2005年11月23日、マッツは次のように述べています。

|> Don't use it please.  I'm regretting this feature, and I'd like to
|> remove it in the future if it's possible.
|
|I'm surprised.  What do you regret about it?

Because it's hard for users to tell

  begin <code> end while <cond>

works differently from

  <code> while <cond>

RosettaCode wiki にも同様のストーリーがあります:

  

2005年11月、Rubyの作成者である松本幸宏は、このループ機能を後悔し、Kernel#loopの使用を提案しました。

他のヒント

  

Rubyコアライブラリの Tempfile#initialize のソースを読み取り中に、次のスニペットを見つけました。

begin
  tmpname = File.join(tmpdir, make_tmpname(basename, n))
  lock = tmpname + '.lock'
  n += 1
end while @@cleanlist.include?(tmpname) or
  File.exist?(lock) or File.exist?(tmpname)
     

一見、begin ... endの内容の前にwhile修飾子が評価されると仮定しましたが、そうではありません。観察:

>> begin
?>   puts "do {} while ()" 
>> end while false
do {} while ()
=> nil
     

期待どおり、ループは修飾子がtrueの間実行を続けます。

>> n = 3
=> 3
>> begin
?>   puts n
>>   n -= 1
>> end while n > 0
3
2
1
=> nil
     

このイディオムを二度と見たくないのですが、begin ... endは非常に強力です。以下は、パラメータなしで1行メソッドをメモする一般的なイディオムです。

def expensive
  @expensive ||= 2 + 2
end
     

これはいですが、もっと複雑なものを簡単にメモする方法です:

def expensive
  @expensive ||=
    begin
      n = 99
      buf = "" 
      begin
        buf << "#{n} bottles of beer on the wall\n" 
        # ...
        n -= 1
      end while n > 0
      buf << "no more bottles of beer" 
    end
end

元は Jeremy Voorhis によって作成されました。元のサイトから削除されたと思われるため、コンテンツはここにコピーされました。コピーはウェブアーカイブおよび Rubyバズフォーラム。 -トカゲの請求書

これに似ています:

people = []

begin
  info = gets.chomp
  people += [Person.new(info)] if not info.empty?
end while not info.empty?

リファレンス: RubyのHidden do {} while()Loop

これはどうですか?

people = []

until (info = gets.chomp).empty?
  people += [Person.new(info)]
end

これは、hubbardrの私のブログへのリンクからの全文記事です。

Rubyコアライブラリの Tempfile#initialize のソースを読み取り中に、次のスニペットを見つけました。

begin
  tmpname = File.join(tmpdir, make_tmpname(basename, n))
  lock = tmpname + '.lock'
  n += 1
end while @@cleanlist.include?(tmpname) or
  File.exist?(lock) or File.exist?(tmpname)

一見、 while 修飾子は begin ... end の内容の前に評価されると仮定しましたが、そうではありません。観察:

>> begin
?>   puts "do {} while ()" 
>> end while false
do {} while ()
=> nil

期待どおり、ループは修飾子がtrueの間実行を続けます。

>> n = 3
=> 3
>> begin
?>   puts n
>>   n -= 1
>> end while n > 0
3
2
1
=> nil

このイディオムを二度と見たくないのですが、 begin ... end は非常に強力です。以下は、パラメータなしで1行メソッドをメモする一般的なイディオムです。

def expensive
  @expensive ||= 2 + 2
end

これはいですが、もっと複雑なものを簡単にメモする方法です:

def expensive
  @expensive ||=
    begin
      n = 99
      buf = "" 
      begin
        buf << "#{n} bottles of beer on the wall\n" 
        # ...
        n -= 1
      end while n > 0
      buf << "no more bottles of beer" 
    end
end

これで正しく動作するようになりました。

begin
    # statment
end until <condition>

ただし、将来的には削除される可能性があります。 begin という発言は直観に反しています。見る: http://blade.nagakiut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/6745

Matz は次のようにすることを推奨しました。

loop do
    # ...
    break if <condition>
end

私が収集したものから、マッツはその構造が好きではありません

begin
    <multiple_lines_of_code>
end while <cond>

理由は、セマンティクスが次と異なるためです

<single_line_of_code> while <cond>

最初のコンストラクトは、条件をチェックする前に最初にコードを実行するため、 また、2番目の構造は、コードを実行する前に(もしあれば)最初に条件をテストします。 Matzはifステートメントの1行のコンストラクトに一致するため、2番目のコンストラクトを保持することを好みます。

ifステートメントであっても、2番目の構造は好きではありません。その他の場合はすべて、コンピューター コードを左から右(たとえば、||および&amp;&amp;)で上から下に実行します。人間は左から右にコードを読む 上から下へ。

代わりに次の構成体をお勧めします:

if <cond> then <one_line_code>      # matches case-when-then statement

while <cond> then <one_line_code>

<one_line_code> while <cond>

begin <multiple_line_code> end while <cond> # or something similar but left-to-right

これらの提案が他の言語で解析されるかどうかはわかりません。しかし、いずれにせよ 左から右への実行と言語の一貫性を保つことを好みます。

a = 1
while true
  puts a
  a += 1
  break if a > 10
end

もう1つあります:

people = []
1.times do
  info = gets.chomp
  unless info.empty? 
    people += [Person.new(info)]
    redo
  end
end
ppl = []
while (input=gets.chomp)
 if !input.empty?
  ppl << input
 else
 p ppl; puts "Goodbye"; break
 end
end
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top