web-dev-qa-db-ja.com

Rubyの非表示の機能

「...の隠された機能」ミームを続けて、あまり知られていないが有用なRubyプログラミング言語の機能を共有しましょう。

この議論を、Ruby on Rails stuff。

こちらもご覧ください:

(回答ごとにone隠し機能のみを入力してください。)

ありがとうございました

160
squadette

From Ruby 1.9 Proc#===はProc#callのエイリアスです。つまり、Procオブジェクトは次のようなcaseステートメントで使用できます。

def multiple_of(factor)
  Proc.new{|product| product.modulo(factor).zero?}
end

case number
  when multiple_of(3)
    puts "Multiple of 3"
  when multiple_of(7)
    puts "Multiple of 7"
end
80
Farrel

Peter Cooperには、 良いリスト of Rubyトリックがあります。おそらく私のお気に入りは、単一のアイテムとコレクションの両方を列挙できるようにすることです。そのオブジェクトだけを含むコレクションとしてのコレクションオブジェクト。)次のようになります。

[*items].each do |item|
  # ...
end
76
James A. Rosen

これがどのように隠されているかわかりませんが、1次元配列からハッシュを作成する必要があるときに便利だとわかりました。

fruit = ["Apple","red","banana","yellow"]
=> ["Apple", "red", "banana", "yellow"]

Hash[*fruit]    
=> {"Apple"=>"red", "banana"=>"yellow"}
64
astronautism

私が好きなトリックの1つは、感嘆符(*)配列以外のオブジェクトのエキスパンダー。正規表現の一致の例を次に示します。

match, text, number = *"Something 981".match(/([A-z]*) ([0-9]*)/)

その他の例は次のとおりです。

a, b, c = *('A'..'Z')

Job = Struct.new(:name, :occupation)
tom = Job.new("Tom", "Developer")
name, occupation = *tom
54
tomafro

うわー、誰もフリップフロップ演算子に言及していません:

1.upto(100) do |i|
  puts i if (i == 3)..(i == 15)
end
52

Rubyの素晴らしい点の1つは、メソッドやクラスの定義など、他の言語が眉をひそめるような場所でメソッドを呼び出してコードを実行できることです。

たとえば、実行時までランダムな未知のスーパークラスを持つクラスを作成するには、次のようにします。

class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample

end

RandomSubclass.superclass # could output one of 6 different classes.

これは1.9 Array#sampleメソッド(1.8.7のみ、Array#choiceを参照)を使用します。この例はかなり不自然ですが、ここでその威力を見ることができます。

別のクールな例は、固定されていないデフォルトのパラメーター値を配置する機能です(他の言語がしばしば要求するように):

def do_something_at(something, at = Time.now)
   # ...
end

もちろん、最初の例の問題は、呼び出し時ではなく定義時に評価されることです。したがって、スーパークラスが選択されると、プログラムの残りの間、そのスーパークラスのままになります。

ただし、2番目の例では、do_something_atを呼び出すたびに、at変数はメソッドが呼び出された時間になります(まあ、非常に近い)

49
Bo Jeanes

別の小さな機能-Fixnumを最大36までの任意のベースに変換します。

>> 1234567890.to_s(2)
=> "1001001100101100000001011010010"

>> 1234567890.to_s(8)
=> "11145401322"

>> 1234567890.to_s(16)
=> "499602d2"

>> 1234567890.to_s(24)
=> "6b1230i"

>> 1234567890.to_s(36)
=> "kf12oi"

Huw Waltersがコメントしたように、他の方法を変換するのも同じくらい簡単です。

>> "kf12oi".to_i(36)
=> 1234567890
47
tomafro

デフォルト値でハッシュ!この場合の配列。

parties = Hash.new {|hash, key| hash[key] = [] }
parties["Summer party"]
# => []

parties["Summer party"] << "Joe"
parties["Other party"] << "Jane"

メタプログラミングに非常に役立ちます。

40
August Lilleaas

Ruby 1.9ソースをダウンロードし、make golf、次のようなことができます:

make golf

./goruby -e 'h'
# => Hello, world!

./goruby -e 'p St'
# => StandardError

./goruby -e 'p 1.tf'
# => 1.0

./goruby19 -e 'p Fil.exp(".")'
"/home/manveru/pkgbuilds/Ruby-svn/src/trunk"

読む golf_prelude.cよりきちんとしたものを隠すために。

39
manveru

1.9 Proc機能のもう1つの楽しい追加機能は、Proc#curryです。これにより、n個の引数を受け入れるProcを、n-1を受け入れるものに変えることができます。ここで、上記のProc#=== tipと組み合わせます。

it_is_day_of_week = lambda{ |day_of_week, date| date.wday == day_of_week }
it_is_saturday = it_is_day_of_week.curry[6]
it_is_sunday = it_is_day_of_week.curry[0]

case Time.now
when it_is_saturday
  puts "Saturday!"
when it_is_sunday
  puts "Sunday!"
else
  puts "Not the weekend"
end
38
Farrel

非ブール値のブール演算子。

&&および||

どちらも、最後に評価された式の値を返します。

||=は、変数が未定義の場合、右側の値を返す式で変数を更新します。これは明示的に文書化されているのではなく、一般的な知識です。

しかし &&=はあまり広く知られていません。

string &&= string + "suffix"

と同等です

if string
  string = string + "suffix"
end

変数が未定義の場合、続行すべきではない破壊的な操作に非常に便利です。

35
EmFi

Railsが提供するSymbol#to_proc関数は本当にクールです。

の代わりに

Employee.collect { |emp| emp.name }

あなたは書ける:

Employee.collect(&:name)
29
hoyhoy

最後の1つ-Rubyでは、文字列を区切る任意の文字を使用できます。次のコードを使用します。

message = "My message"
contrived_example = "<div id=\"contrived\">#{message}</div>"

文字列内の二重引用符をエスケープしたくない場合は、単に別の区切り文字を使用できます。

contrived_example = %{<div id="contrived-example">#{message}</div>}
contrived_example = %[<div id="contrived-example">#{message}</div>]

区切り文字をエスケープする必要を回避するだけでなく、より良い複数行の文字列にこれらの区切り文字を使用できます。

sql = %{
    SELECT strings 
    FROM complicated_table
    WHERE complicated_condition = '1'
}
28
tomafro

define_methodコマンドを使用して動的にメソッドを生成すると、非常に興味深く、あまり知られていないことがわかります。例えば:

((0..9).each do |n|
    define_method "press_#{n}" do
      @number = @number.to_i * 10 + n
    end
  end

上記のコードは「define_method」コマンドを使用して、「press1」から「press9」までのメソッドを動的に作成します。本質的に同じコードを含む10個のメソッドすべてを入力するのではなく、define methodコマンドを使用して、必要に応じてこれらのメソッドをオンザフライで生成します。

26

Rangeオブジェクトを無限の遅延リストとして使用します。

Inf = 1.0 / 0

(1..Inf).take(5) #=> [1, 2, 3, 4, 5]

詳細はこちら: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-Ruby/

26
horseyguy

module_function

module_functionとして宣言されたモジュールメソッドは、モジュールを含むクラスでprivateインスタンスメソッドとして自身のコピーを作成します。

module M
  def not!
    'not!'
  end
  module_function :not!
end

class C
  include M

  def fun
    not!
  end
end

M.not!     # => 'not!
C.new.fun  # => 'not!'
C.new.not! # => NoMethodError: private method `not!' called for #<C:0x1261a00>

引数なしでmodule_functionを使用すると、module_functionステートメントの後に来るモジュールメソッドはすべて自動的にmodule_functionsになります。

module M
  module_function

  def not!
    'not!'
  end

  def yea!
    'yea!'
  end
end


class C
  include M

  def fun
    not! + ' ' + yea!
  end
end
M.not!     # => 'not!'
M.yea!     # => 'yea!'
C.new.fun  # => 'not! yea!'
23
newtonapple

次のような短い注入:

範囲の合計:

(1..10).inject(:+)
=> 55
23
user130730

警告:このアイテムは#12008年の最も恐ろしいハックに投票されたため、注意して使用してください。実際、ペストのようにそれを避けてください、しかしそれは最も確かに隠されたルビーです。

SuperatorsはRubyに新しい演算子を追加します

あなたのコードのユニークな操作のために、極秘のハンドシェイク演算子が必要ですか?コードゴルフをするのが好きですか? -〜+〜-または<---のような演算子を試してください。最後の演算子は、アイテムの順序を逆にするための例で使用されています。

Superators Project とは何の関係もありません。

21
Captain Hammer

私はパーティーに遅れていますが、:

2つの等しい長さの配列を簡単に取得し、1つの配列がキーを提供し、もう1つの配列が値を提供するハッシュに変換できます。

a = [:x, :y, :z]
b = [123, 456, 789]

Hash[a.Zip(b)]
# => { :x => 123, :y => 456, :z => 789 }

(これは、Array#Zipが2つの配列から値を「圧縮」するために機能します。

a.Zip(b)  # => [[:x, 123], [:y, 456], [:z, 789]]

そして、Hash []はまさにそのような配列を取ることができます。私は人々がこれを行うのを見てきました:

Hash[*a.Zip(b).flatten]  # unnecessary!

どちらが同じ結果をもたらしますが、スプラットとフラット化は完全に不要です-おそらくそれらは過去になかったのでしょうか?)

19
Jordan Running

Rubyでのハッシュの自動有効化

def cnh # silly name "create nested hash"
  Hash.new {|h,k| h[k] = Hash.new(&h.default_proc)}
end
my_hash = cnh
my_hash[1][2][3] = 4
my_hash # => { 1 => { 2 => { 3 =>4 } } }

これは便利です。

19
Trevoke

配列の破壊

(a, b), c, d = [ [:a, :b ], :c, [:d1, :d2] ]

どこで:

a #=> :a
b #=> :b
c #=> :c
d #=> [:d1, :d2]

この手法を使用すると、単純な割り当てを使用して、任意の深さのネストされた配列から必要な正確な値を取得できます。

16
horseyguy

Class.new()

実行時に新しいクラスを作成します。引数は派生元のクラスにすることができ、ブロックはクラス本体です。また、const_set/const_get/const_defined?は、新しいクラスを適切に登録し、inspectが数字ではなく名前を出力するようにします。

毎日必要なものではありませんが、必要なときに非常に便利です。

15
Justin Love

連続番号の配列を作成します。

x = [*0..5]

xを[0、1、2、3、4、5]に設定します

13
horseyguy

Rubylandで見られる多くの魔法は、メタプログラミングに関係しています。メタプログラミングとは、単にコードを書くコードを書くことです。 Rubyのattr_accessorattr_reader、およびattr_writerはすべて、単純なメタプログラミングであり、標準パターンに従って2行のメソッドを1行で作成します。 Railsは、has_onebelongs_toなどのリレーションシップ管理メソッドを使用して、多くのメタプログラミングを実行します。

ただし、class_evalを使用して動的に記述されたコードを実行する独自のメタプログラミングトリックを作成するのは非常に簡単です。

次の例では、ラッパーオブジェクトが特定のメソッドを内部オブジェクトに転送できるようにします。

class Wrapper
  attr_accessor :internal

  def self.forwards(*methods)
    methods.each do |method|
      define_method method do |*arguments, &block|
        internal.send method, *arguments, &block
      end
    end
  end

  forwards :to_i, :length, :split
end

w = Wrapper.new
w.internal = "12 13 14"
w.to_i        # => 12
w.length      # => 8
w.split('1')  # => ["", "2 ", "3 ", "4"]

メソッドWrapper.forwardsは、メソッド名のシンボルを受け取り、methods配列に格納します。次に、指定されたそれぞれに対して、define_methodを使用して、すべての引数とブロックを含めて、メッセージを一緒に送信する新しいメソッドを作成します。

メタプログラミングの問題に関する優れたリソースは、 なぜラッキースティフの「メタプログラミングを明確に見る」 です。

13
TALlama

ケースの比較には、===(obj)に応答するものをすべて使用します。

case foo
when /baz/
  do_something_with_the_string_matching_baz
when 12..15
  do_something_with_the_integer_between_12_and_15
when lambda { |x| x % 5 == 0 }
  # only works in Ruby 1.9 or if you alias Proc#call as Proc#===
  do_something_with_the_integer_that_is_a_multiple_of_5
when Bar
  do_something_with_the_instance_of_Bar
when some_object
  do_something_with_the_thing_that_matches_some_object
end

Module(したがってClass)、RegexpDate、および他の多くのクラスはインスタンスメソッドを定義します:===(other)。利用される。

Farrel のおかげで、Proc#callエイリアスとしてProc#=== in Ruby 1.9。

12
James A. Rosen

「Ruby」バイナリ(少なくともMRIの)は、Perlのワンライナーを非常に人気にした多くのスイッチをサポートします。

重要なもの:

  • -n「gets」だけで外側のループを設定します-これは指定されたファイル名またはSTDINで魔法のように動作し、$ _の各読み取り行を設定します
  • -p -nに似ていますが、各ループの反復の最後に自動putsを使用します
  • -$ Fに保存されている各入力行での.splitの自動呼び出し
  • -i入力ファイルのインプレース編集
  • -l入力時の.chompの自動呼び出し
  • -eコードを実行します
  • -cソースコードをチェックします
  • -w警告付き

いくつかの例:

# Print each line with its number:
Ruby -ne 'print($., ": ", $_)' < /etc/irbrc

# Print each line reversed:
Ruby -lne 'puts $_.reverse' < /etc/irbrc

# Print the second column from an input CSV (dumb - no balanced quote support etc):
Ruby -F, -ane 'puts $F[1]' < /etc/irbrc

# Print lines that contain "eat"
Ruby -ne 'puts $_ if /eat/i' < /etc/irbrc

# Same as above:
Ruby -pe 'next unless /eat/i' < /etc/irbrc

# Pass-through (like cat, but with possible line-end munging):
Ruby -p -e '' < /etc/irbrc

# Uppercase all input:
Ruby -p -e '$_.upcase!' < /etc/irbrc

# Same as above, but actually write to the input file, and make a backup first with extension .bak - Notice that inplace edit REQUIRES input files, not an input STDIN:
Ruby -i.bak -p -e '$_.upcase!' /etc/irbrc

「Ruby one-liners」と「Perl one-liners」をグーグルで検索して、より多くの実用的で実用的な例をご覧ください。基本的に、Rubyをawkとsedのかなり強力な代替として使用できます。

11
minaguib

send()メソッドは、Rubyの任意のクラスまたはオブジェクトで使用できる汎用メソッドです。オーバーライドされない場合、send()はストリングを受け入れ、ストリングが渡されるメソッドの名前を呼び出します。たとえば、ユーザーが「Clr」ボタンをクリックすると、「press_clear」文字列がsend()メソッドに送信され、「press_clear」メソッドが呼び出されます。 send()メソッドにより、Rubyで関数を呼び出す楽しさと動的な方法が可能になります。

 %w(7 8 9 / 4 5 6 * 1 2 3 - 0 Clr = +).each do |btn|
    button btn, :width => 46, :height => 46 do
      method = case btn
        when /[0-9]/: 'press_'+btn
        when 'Clr': 'press_clear'
        when '=': 'press_equals'
        when '+': 'press_add'
        when '-': 'press_sub'
        when '*': 'press_times'
        when '/': 'press_div'
      end

      number.send(method)
      number_field.replace strong(number)
    end
  end

Blogging Shoes:The Simple-Calc Application でこの機能について詳しく説明します

10
private unless Rails.env == 'test'
# e.g. a bundle of methods you want to test directly

Rubyのクールで(場合によっては)素敵で便利なハック/機能のように見えます。

9
Szymon Jeż

Fixnum#to_s(base)は、場合によっては非常に便利です。そのようなケースの1つは、36の基数を使用して乱数を文字列に変換することにより、ランダム(擬似)固有トークンを生成することです。

長さ8のトークン:

Rand(36**8).to_s(36) => "fmhpjfao"
Rand(36**8).to_s(36) => "gcer9ecu"
Rand(36**8).to_s(36) => "krpm0h9r"

長さ6のトークン:

Rand(36**6).to_s(36) => "bvhl8d"
Rand(36**6).to_s(36) => "lb7tis"
Rand(36**6).to_s(36) => "ibwgeh"
9
sickill

本当に必要のないものが必要だと言っているクラスやモジュールをだます:

$" << "something"

これは、たとえばBを必要とするAを必要とするが、コードでBを必要としない場合に役立ちます(Aはコードでも使用しません)。

たとえば、Backgroundrbのbdrb_test_helper requires'test/spec'、しかしあなたはそれをまったく使用しないので、あなたのコードで:

$" << "test/spec"
require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
9
olegueret

任意の数のパラメーターを受け入れ、それらをすべて破棄するメソッドの定義

def hello(*)
    super
    puts "hello!"
end

上記のhelloメソッドはputs"hello"画面でsuperを呼び出しますが、スーパークラスhelloもパラメーターを定義するため、パラメーターを定義する必要があります-ただし、実際にパラメーター自体を使用する必要がないため、彼らに名前を付けなければなりません。

9
horseyguy

複数の正規表現を|と組み合わせるには、次を使用できます。

Regexp.union /Ruby\d/, /test/i, "cheat"

次のような正規表現を作成するには:

/(Ruby\d|[tT][eE][sS][tT]|cheat)/
8
J-_-L

これはいくつかのスクリプトで役立ちます。シェルスクリプトやMakefileのように、環境変数を直接使用することができます。環境変数は、未定義Ruby定数のフォールバックとして使用されます。

>> class <<Object
>>  alias :old_const_missing :const_missing
>>  def const_missing(sym)
>>   ENV[sym.to_s] || old_const_missing(sym)
>>  end
>> end
=> nil

>> puts Shell
/bin/zsh
=> nil
>> TERM == 'xterm'
=> true
8
Ropez

ARGV [0]に基づいてファイルを開くのはどうですか?

readfile.rb:

$<.each_line{|l| puts l}

Ruby readfile.rb testfile.txt

これは、1回限りのスクリプトを作成するための優れたショートカットです。ほとんどの人が知らない事前定義された変数の混乱があります。それらを賢く使用してください(読んでください:維持しようとしているコードベースを散らかさないでください。散らかってしまいます)。

8
Scott Holden

私はのファンです:

%w{An Array of strings} #=> ["An", "Array", "of", "Strings"]

それがどれほど有用であるかは、ちょっとおかしいです。

5
Judson

複数の戻り値

def getCostAndMpg
    cost = 30000  # some fancy db calls go here
    mpg = 30
    return cost,mpg
end
AltimaCost, AltimaMpg = getCostAndMpg
puts "AltimaCost = #{AltimaCost}, AltimaMpg = #{AltimaMpg}"

並列割り当て

i = 0
j = 1
puts "i = #{i}, j=#{j}"
i,j = j,i
puts "i = #{i}, j=#{j}"

仮想属性

class Employee < Person
  def initialize(fname, lname, position)
    super(fname,lname)
    @position = position
  end
  def to_s
     super + ", #@position"
  end
  attr_writer :position
  def etype
     if @position == "CEO" || @position == "CFO"
         "executive"
     else
         "staff"
     end
  end
end
employee = Employee.new("Augustus","Bondi","CFO")
employee.position = "CEO"
puts employee.etype    =>  executive
employee.position = "Engineer"
puts employee.etype    =>  staff

method_missing-素晴らしいアイデア

(メソッドが見つからず、エラーがスローされ、プログラムが停止するほとんどの言語。InRuby実際にこれらのエラーをキャッチし、状況に応じてインテリジェントな処理を行うことができます)

class MathWiz
  def add(a,b) 
    return a+b
  end
  def method_missing(name, *args)
    puts "I don't know the method #{name}"
  end
end
mathwiz = MathWiz.new
puts mathwiz.add(1,4)
puts mathwiz.subtract(4,2)

5

減算方法がわからない

なし

5
Ramiz Uddin

James A. Rosenのヒントは素晴らしい([* items] .each)ですが、ハッシュが破壊されることがわかりました。

irb(main):001:0> h = {:name => "Bob"}
=> {:name=>"Bob"}
irb(main):002:0> [*h]
=> [[:name, "Bob"]]

処理するもののリストを受け入れますが、寛大であり、呼び出し元がリストを提供できるようにする場合、私はこのケースの処理方法を好みます:

irb(main):003:0> h = {:name => "Bob"}
=> {:name=>"Bob"}
irb(main):004:0> [h].flatten
=> [{:name=>"Bob"}]

これは、次のようにメソッドシグネチャと組み合わせることができます。

def process(*entries)
  [entries].flatten.each do |e|
    # do something with e
  end
end
4
minaguib

私はちょうどloveインラインキーワードrescueのように:
編集された例:

@user #=> nil (but I did't know)
@user.name rescue "Unknown"
link_to( d.user.name, url_user( d.user.id, d.user.name)) rescue 'Account removed'

これは私のアプリを壊すことを避け、Rails。try()でリリースされた機能よりもはるかに優れています

4
Fabiano Soriani

オーバーライドされた場合でも、継承チェーンのどこかで定義されたメソッドを呼び出す

ActiveSupportのオブジェクトは、組み込みオブジェクトになりすますことがあります。

 require 'active_support' 
 days = 5.days 
 days.class#=> Fixnum 
 days.is_a?(Fixnum)#=> true 
 Fixnum === days#=> false(えっ?本当は何ですか?)
 Object.instance_method(:class).bind(days).call#=> ActiveSupport :: Duration(aha!) 
 ActiveSupport :: Duration === days#=> true 

もちろん、上記は、active_supportがObject#instance_methodを再定義しないという事実に依存しています。この場合、実際には小川になります。それから、サードパーティのライブラリがロードされる前に、Object.instance_method(:class)の戻り値をいつでも保存できます。

Object.instance_method(...)は、そのクラスのインスタンスにバインドできるUnboundMethodを返します。この場合、Objectの任意のインスタンス(サブクラスを含む)にバインドできます。

オブジェクトのクラスにモジュールが含まれる場合、それらのモジュールからUnboundMethodを使用することもできます。

 module Mod 
 def var_add(more); @ var + more; end 
 end 
 class Cla 
 include Mod 
 def initialize(var); @ var = var; end 
#override 
 def var_add(more); @ var + more + more; end 
 end 
 cla = Cla.new( 'abcdef')
 cla.var_add( 'ghi')#=> "abcdefghighi" 
 Mod.instance_method( :var_add).bind(cla).call( 'ghi')#=> "abcdefghi" 

これは、オブジェクトが属するクラスのインスタンスメソッドをオーバーライドするシングルトンメソッドでも機能します。

 class Foo 
 def mymethod; '元の'; end 
 end 
 foo = Foo.new 
 foo.mymethod#=> 'original' 
 def foo.mymethod; 「シングルトン」; end 
 foo.mymethod#=> 'singleton' 
 Foo.instance_method(:mymethod).bind(foo).call#=> 'original' 
 
 #シングルトンクラスで#instanceメソッドを呼び出すこともできます。
 class << foo;自己; end.instance_method(:mymethod).bind(foo).call#=> 'singleton' 
4
Kelvin

シンボルリテラルには、知っておくべき側面がいくつかあります。特殊なシンボルリテラルによって解決されるケースの1つは、通常のシンボルリテラル構文で何らかの理由で構文エラーが発生する名前のシンボルを作成する必要がある場合です。

:'class'

シンボル補間を行うこともできます。アクセサーのコンテキストでは、例えば:

define_method :"#{name}=" do |value|
  instance_variable_set :"@#{name}", value
end
3
Tom

each_with_index列挙可能なオブジェクト(配列、ハッシュなど)のメソッドでしょうか?

myarray = ["la", "li", "lu"]
myarray.each_with_index{|v,idx| puts "#{idx} -> #{v}"}

#result:
#0 -> la
#1 -> li
#2 -> lu

他の回答よりもよく知られているかもしれませんが、すべてのRubyプログラマー:)

3
mhd
class A

  private

  def my_private_method
    puts 'private method called'
  end
end

a = A.new
a.my_private_method # Raises exception saying private method was called
a.send :my_private_method # Calls my_private_method and prints private method called'
2
Chirantan

Rubyには call/cc メカニズムがあり、スタックを自由に飛び降りることができます。

簡単な例を次に示します。これは確かにRubyでシーケンスを乗算する方法ではありませんが、call/ccを使用してスタックに到達してアルゴリズムを短絡させる方法を示しています。この場合、すべての数値が表示されるか、ゼロ(答えがわかっている2つのケース)が表示されるまで、数値のリストを再帰的に乗算します。ゼロの場合、リストの任意の深さで終了できます。

#!/usr/bin/env Ruby

def rprod(k, rv, current, *nums)
  puts "#{rv} * #{current}"
  k.call(0) if current == 0 || rv == 0
  nums.empty? ? (rv * current) : rprod(k, rv * current, *nums)
end

def prod(first, *rest)
  callcc { |k| rprod(k, first, *rest) }
end

puts "Seq 1:  #{prod(1, 2, 3, 4, 5, 6)}"
puts ""
puts "Seq 2:  #{prod(1, 2, 0, 3, 4, 5, 6)}"

出力はここで見ることができます:

http://codepad.org/Oh8ddh9e

スタック上の他の方向に移動する継続を特徴とするより複雑な例については、ソースを Generator に読みます。

2
Dustin

私はすべての答えを読みました... 1つの顕著な省略は割り当ての破壊でした:

> (a,b),c = [[1,2],3]
=> [[1,2],3]
> a
=> 1

ブロックパラメーターに対しても機能します。これは、各要素が個別の何かを表すネストされた配列がある場合に便利です。 「array [0] [1]」のようなコードを記述する代わりに、そのネストされた配列を分解して、コードの1行で各要素に説明的な名前を付けることができます。

2
Alex D
@user #=> nil (but I did't know)
@user.name rescue "Unknown"
2
haoqi

Sprintfショートカット

私のお気に入りRuby機能。構文はformat_string % argument

"%04d"  % 1         # => "0001"
"%0.2f" % Math::PI  # => "3.14"

配列(format_string % array_of_arguments

"%.2f %.3f %.4f" % ([Math::PI]*3) 
# => "3.14 3.142 3.1416"
1
iblue