わかりました、あなたは不明確です。
rubyのローカル変数は、小文字( 、、、、など)fooで始まり、字句スコープ(変数など)になります。それらは「クラスのインスタンス」とは何の関係もありませんbarsteveC
@rubyのインスタンス変数は、シジル(、、、、など)@fooで始まり、の現在の値が格納されているオブジェクトである場合は常にスコープ内にあります。@bar@carlself
オブジェクトのインスタンス変数に直接アクセスできるメソッドが必要な場合、それはインスタンスメソッドと呼ばれます。たとえば、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、ブロックを独立した、オブジェクトのように機能させるために使用されるキーワードを意味します(それ自体は通常、lambdas、procs、またはProcsと呼ばれます)。
bounce = lambda { |thing| puts "I'm bouncing a #{thing}" }
bounce["ball"]
bounce["frog"]
ですから、あなたが求めているのは、メソッドの引数としてProcaの代わりに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"]