わかりました、あなたは不明確です。
rubyのローカル変数は、小文字( 、、、、など)foo
で始まり、字句スコープ(変数など)になります。それらは「クラスのインスタンス」とは何の関係もありませんbar
steve
C
@
rubyのインスタンス変数は、シジル(、、、、など)@foo
で始まり、の現在の値が格納されているオブジェクトである場合は常にスコープ内にあります。@bar
@carl
self
オブジェクトのインスタンス変数に直接アクセスできるメソッドが必要な場合、それはインスタンスメソッドと呼ばれます。たとえば、battle_cry
とinitialize
は両方ともインスタンスメソッドです。
class Character
def initialize(name)
@name=name
end
def battle_cry
@name.upcase + "!!!"
end
def Character.default
new("Leeroy Jenkins")
end
end
対照的に、クラスメソッドはClass
オブジェクトのメソッドであり、そのオブジェクトのインスタンス変数にはアクセスできません。上記の例で
default
は、はクラスメソッドです。
現在のスコープの変更をトリガーする、または現在のスコープから値を取得する(クラスまたはインスタンス)メソッドが必要な場合、rubyはブロックと呼ばれるタイプのコールバックを使用します。
class Character
ATTACKS = [ "Ho!", "Haha!", "Guard!", "Turn!", "Parry!", "Dodge!", "Spin!", "Ha", "THRUST!" ]
def attack
ATTACKS.inject(0) { |dmg, word| dmg + yield(word) }
end
end
person = Character.default
puts person.battle_cry
num_attacks = 0;
damage = person.attack do |saying|
puts saying
num_attacks += 1
rand(3)
end
puts "#{damage} points of damage done in #{num_attacks} attacks"
上記の例でattack
は、yield
キーワードを使用して、渡されたブロックを呼び出します。を呼び出すとattack
、ローカル変数num_attacks
は、渡すブロック(ここではで区切られますdo ... end
)のスコープ内にあるため、インクリメントできます。 attack
はブロックに値を渡すことができます。ここでは、値が変数にキャプチャされsaying
ます。ブロックはまた、値をメソッドに返します。これは、の戻り値として表示されますyield
。
lambda
ルビーの単語は通常lambda
、ブロックを独立した、オブジェクトのように機能させるために使用されるキーワードを意味します(それ自体は通常、lambda
s、proc
s、またはProc
sと呼ばれます)。
bounce = lambda { |thing| puts "I'm bouncing a #{thing}" }
bounce["ball"]
bounce["frog"]
ですから、あなたが求めているのは、メソッドの引数としてProc
aの代わりにaを渡すことができるかどうかだと思います。Hash
そして答えは「状況次第」です。メソッドがメソッドのみを使用する場合は#[]
、はい:
class Character
attr_accessor :stats
def set_stats(stats)
@stats = stats
end
end
frank = Character.new("Victor Frankenstein")
frank.set_stats({ :str => 7, :dex => 14, :con => 9, :int => 19, :wis => 7, :cha => 11 })
monster = Character.new("Frankenstein's Monster")
monster.set_stats(lambda do |stat_name|
rand(20)
end)
ただし、他のHash
特定のメソッドを使用したり、同じキーを複数回呼び出したりすると、奇妙な結果が生じる可能性があります。
monster = Character.new("Frankenstein's Monster")
monster.set_stats(lambda do |stat_name|
rand(20)
end)
monster.stats[:dex] #=> 19
monster.stats[:dex] #=> 1
その場合は、リクエストを中間ハッシュにキャッシュしたほうがよい場合があります。Hash
はイニシャライザブロックを持つことができるため、これはかなり簡単です。したがって、上記を次のように変更すると、次のようになります。
monster.set_stats(Hash.new do |stats_hash, stat_name|
stats_hash[stat_name] = rand(20)
end)
monster.stats[:dex] #=> 3
monster.stats[:dex] #=> 3
結果はハッシュにキャッシュされます
Hash
ブロック初期化子の詳細については、以下を参照してくださいri Hash::new
。
-------------------------------------------------------------- Hash::new
Hash.new => hash
Hash.new(obj) => aHash
Hash.new {|hash, key| block } => aHash
------------------------------------------------------------------------
Returns a new, empty hash. If this hash is subsequently accessed
by a key that doesn't correspond to a hash entry, the value
returned depends on the style of new used to create the hash. In
the first form, the access returns nil. If obj is specified, this
single object will be used for all default values. If a block is
specified, it will be called with the hash object and the key, and
should return the default value. It is the block's responsibility
to store the value in the hash if required.
h = Hash.new("Go Fish")
h["a"] = 100
h["b"] = 200
h["a"] #=> 100
h["c"] #=> "Go Fish"
# The following alters the single default object
h["c"].upcase! #=> "GO FISH"
h["d"] #=> "GO FISH"
h.keys #=> ["a", "b"]
# While this creates a new default object each time
h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
h["c"] #=> "Go Fish: c"
h["c"].upcase! #=> "GO FISH: C"
h["d"] #=> "Go Fish: d"
h.keys #=> ["c", "d"]