159

「~の隠れた機能」の続きで、Ruby プログラミング言語のあまり知られていないが便利な機能を共有しましょう。

この議論は、Ruby on Rails に関するものは一切含まず、コア Ruby に限定してください。

以下も参照してください。

(回答ごとに隠し機能を 1つだけにしてください。)

ありがとうございました

4

46 に答える 46

80

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
于 2008-09-15T17:41:22.660 に答える
76

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

[*items].each do |item|
  # ...
end
于 2008-09-15T16:31:32.313 に答える
64

これがどれほど隠されているかはわかりませんが、1 次元配列からハッシュを作成する必要がある場合に役立つことがわかりました。

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

Hash[*fruit]    
=> {"apple"=>"red", "banana"=>"yellow"}
于 2008-09-16T07:53:31.863 に答える
54

私が気に入っているトリックの 1 つは*、配列以外のオブジェクトで splat() エキスパンダーを使用することです。正規表現一致の例を次に示します。

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
于 2008-09-16T08:14:19.460 に答える
51

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

1.upto(100) do |i|
  puts i if (i == 3)..(i == 15)
end
于 2010-06-16T15:23:36.663 に答える
49

ruby の優れた点の 1 つは、メソッドやクラスの定義など、他の言語では難しそうな場所でメソッドを呼び出してコードを実行できることです。

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

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

end

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

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

もう 1 つのクールな例は、固定されていないデフォルトのパラメーター値を設定できる機能です (他の言語でよく要求されるように)。

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

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

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

于 2009-01-23T22:35:34.483 に答える
47

別の小さな機能 - aFixnumを 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
于 2008-09-17T16:56:16.200 に答える
40

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

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

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

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

于 2009-06-30T05:09:36.623 に答える
38

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

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
于 2008-09-16T07:39:33.333 に答える
38

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隠れているよりきちんとしたものについては、 をお読みください。

于 2008-09-15T15:49:07.377 に答える
35

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

&&||

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

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

ただし、&&=これについてはあまり広く知られていません。

string &&= string + "suffix"

と同等です

if string
  string = string + "suffix"
end

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

于 2009-12-21T17:32:42.360 に答える
29

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

それ以外の

Employee.collect { |emp| emp.name }

あなたは書ける:

Employee.collect(&:name)
于 2008-09-16T00:22:09.890 に答える
28

最後の 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'
}
于 2008-09-17T18:40:01.443 に答える
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/

于 2009-11-30T03:30:00.283 に答える
25

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 コマンドを使用して、必要に応じてこれらのメソッドをオンザフライで生成します。

于 2008-09-15T15:44:16.140 に答える
23

モジュール関数

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

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!'
于 2008-09-22T18:56:02.837 に答える
21

警告:このアイテムは2008年の最も恐ろしいハックの第1位に選ばれたため、注意して使用してください。実際には、疫病のようにそれを避けてください、しかしそれは間違いなく隠されたルビーです。

スーパーエーターはRubyに新しいオペレーターを追加します

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

私はそれを賞賛する以外にSuperatorsプロジェクトとは何の関係もありません。

于 2008-09-16T03:08:32.643 に答える
19

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

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!

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

于 2009-10-08T21:29:33.787 に答える
19

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 } } }

これは非常に便利です。

于 2010-01-25T14:13:23.127 に答える
16

配列の破壊

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

どこ:

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

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

于 2010-09-29T16:43:06.607 に答える
15

Class.new()

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

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

于 2008-10-22T02:28:07.743 に答える
13

Rubyland で見られる魔法の多くは、メタプログラミングと関係があります。メタプログラミングとは、単にコードを書くコードを書くことです。Ruby のattr_accessorattr_reader、およびattr_writerはすべて単純なメタプログラミングであり、標準パターンに従って 1 行で 2 つのメソッドを作成します。has_oneRails は、や などの関係管理メソッドを使用して、多くのメタプログラミングを行いbelongs_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すべての引数とブロックを含むメッセージを送信する新しいメソッドを作成します。

メタプログラミングの問題に関する優れたリソースは、Why the Lucky Stiff の "Seeing Metaprogramming Clearly"です。

于 2008-09-15T17:31:17.413 に答える
13

連続する数字の配列を作成します。

x = [*0..5]

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

于 2009-08-03T20:44:51.360 に答える
12

===(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) を定義し、すべて使用できます。

Ruby 1.9のようにエイリアス化されていることを思い出させてくれたFarrelに感謝します。Proc#callProc#===

于 2008-09-15T16:27:50.607 に答える
11

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

重要なもの:

  • -n「gets」だけで外部ループを設定します。これは、指定されたファイル名またはSTDINで魔法のように機能し、各読み取り行を$_に設定します。
  • -p -nに似ていますがput、各ループ反復の最後に自動sがあります
  • -$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

より使いやすく実用的な例については、「ru​​byone-liners」と「perlone-liners」をグーグルで検索してください。基本的に、awkやsedのかなり強力な代替品としてrubyを使用できます。

于 2010-01-02T20:59:28.230 に答える
10

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で詳しく説明しています。

于 2008-09-15T15:45:58.570 に答える
9

クラスまたはモジュールをだまして、実際には必要ではないものが必要であると伝えます。

$" << "something"

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

たとえば、Backgroundrb のbdrb_test_helper requires 'test/spec'ですが、まったく使用しないため、コードでは次のようになります。

$" << "test/spec"
require File.join(File.dirname(__FILE__) + "/../bdrb_test_helper")
于 2008-09-15T23:51:16.860 に答える
9

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

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

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

于 2010-09-30T21:05:44.067 に答える
8

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

readfile.rb:

$<.each_line{|l| puts l}

ruby readfile.rb testfile.txt

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

于 2008-09-15T16:36:01.930 に答える
8

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"
于 2010-02-26T10:05:21.077 に答える
8

これは、いくつかのスクリプトで便利です。シェル スクリプトや 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
于 2009-07-16T21:37:02.900 に答える
8

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

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

次のような正規表現を作成します。

/(Ruby\d|[tT][eE][sS][tT]|cheat)/
于 2011-05-17T20:59:54.080 に答える
5

I'm a fan of:

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

It's sort of funny how often that's useful.

于 2010-05-26T08:58:55.360 に答える
4

複数の戻り値

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-素晴らしいアイデア

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

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

引き算の方法がわからない

nil

于 2010-11-27T22:53:32.883 に答える
4

オーバーライドされている場合でも、継承チェーンの任意の場所で定義されたメソッドを呼び出す

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

「active_support」が必要
日 = 5. 日
days.class #=> Fixnum
days.is_a?(Fixnum) #=> true
Fixnum === 日 #=> false (え?あなたは本当に何ですか?)
Object.instance_method(:class).bind(days).call #=> ActiveSupport::Duration (ああ!)
ActiveSupport::Duration === 日 #=> true

上記はもちろん、active_support が Object#instance_method を再定義しないという事実に依存しています。繰り返しになりますが、サードパーティのライブラリが読み込まれる前に、常に Object.instance_method(:class) の戻り値を保存できます。

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

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

モジュールモッド
  def var_add(もっと); @var+more; 終わり
終わり
クラスクラ
  モッドを含める
  デフ初期化(変数); @var=var; 終わり
  # オーバーライド
  def var_add(もっと); @var+more+more; 終わり
終わり
cla = Cla.new('abcdef')
cla.var_add('ghi') #=> "abcdefghighi"
Mod.instance_method(:var_add).bind(cla).call('ghi') #=> "abcdefghi"

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

クラスフー
  def mymethod; 'オリジナル'; 終わり
終わり
foo = Foo.new
foo.mymethod #=> 'オリジナル'
def foo.mymethod; 'シングルトン'; 終わり
foo.mymethod #=> 'シングルトン'
Foo.instance_method(:mymethod).bind(foo).call #=> 'オリジナル'

# シングルトン クラスで #instance メソッドを呼び出すこともできます。
クラス << foo; 自己; end.instance_method(:mymethod).bind(foo).call #=> 'singleton'
于 2010-11-09T23:05:16.970 に答える
4

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
于 2010-01-02T20:35:05.503 に答える
3

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

:'class'

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

define_method :"#{name}=" do |value|
  instance_variable_set :"@#{name}", value
end
于 2011-03-17T00:06:44.267 に答える
3

私は次のようなインラインキーワードレスキューが大好きです:編集例:

@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()でリリースされた機能よりもはるかに優れています

于 2010-03-04T12:13:38.197 に答える
3

列挙可能なオブジェクト(配列、ハッシュなど)のeach_with_indexメソッドはおそらく?

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

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

他の答えよりもよく知られているかもしれませんが、すべてのRubyプログラマーにとってはそれほど知られていません:)

于 2010-07-27T07:27:56.067 に答える
2

Rubyにはcall/ccメカニズムがあり、スタックを自由に上下に移動できます。

簡単な例を次に示します。これは確かにルビーでシーケンスを乗算する方法ではありませんが、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

スタック上で反対方向に移動する継続を特徴とするより複雑な例については、ソースをジェネレーターに読み取ってください。

于 2008-11-29T05:17:42.317 に答える
2
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'
于 2009-05-06T03:39:40.353 に答える
2

私はすべての答えを読んだだけです...注目すべき省略の1つは、割り当ての破壊でした:

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

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

于 2012-01-19T21:40:14.693 に答える
1
@user #=> nil (but I did't know)
@user.name rescue "Unknown"
于 2010-05-08T03:29:24.247 に答える
1

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"
于 2012-02-09T15:55:09.607 に答える