p Foo.class # Class
employee = Foo.new("smith", 29, "smith@foo.com", "m", 1.75) #create an instance
p employee.class # Foo
p employee.methods.sort # huge list which includes name, name=, age, age= etc
class Foo
@@attributes = [:name, :age, :email, :gender, :height]
@@attributes.each do |attr|
class_eval { attr_accessor "#{attr}" }
end
def initialize params
@@attributes.each do |attr|
instance_variable_set("@#{attr}", params[attr]) if params[attr]
end
end
end
Foo.new({:name => 'test'}).name #=> 'test'
class Foo
attr_reader :p
def initialize p
@p = ->x{p[x]}
end
def foo
do_something_with(@p.(:name))
...
end
end
型 或者,另一种方法是定义一个调用哈希并应用键的方法。
class Foo
def initalize p
@p = p
end
def get key
@p[key]
end
def foo
do_something_with(get(:name))
...
end
end
型 如果要设置值,您可以定义一个setter方法,并进一步检查是否有无效的键。
class Foo
Keys = [:name, :age, :email, :gender, :height]
def initalize p
raise "Invalid key in argument" unless (p.keys - Keys).empty?
@p = p
end
def set key, value
raise "Invalid key" unless Keys.key?(key)
@p[key] = value
end
def get key
@p[key]
end
def foo
do_something_with(get(:name))
...
end
end
module Greeting
def greet
puts "Hello, my name is #{name} and I'm #{age} years old."
end
end
Person = Struct.new(:name, :age) do
include Greeting
end
person = Person.new("Alice", 25)
person.greet # => Hello, my name is Alice and I'm 25 years old.
8条答案
按热度按时间qltillow1#
您可以只迭代键并调用setter。我更喜欢这样,因为如果你传递一个无效的键,它会被捕获。
字符串
zpgglvta2#
字符串
hof1towb3#
为了利用约书亚·奇克的回答,用一点概括
字符串
NB如果初始化mix-in已经被使用 * 并且 * 我们需要自定义初始化,我们只需调用super:
型
gupuwyp24#
字符串
这对于一个功能齐全的类来说已经足够了。演示:
型
rsl1atfo5#
为什么不直接明确地指定一个实际的参数列表呢?
字符串
这个版本可能比其他版本的代码行多,但它使其更容易利用内置的语言特性(例如参数的默认值或在调用
initialize
时引发错误)。omvjsjqw6#
使用params中的所有键是不正确的,你可以定义不愿意的名称。我觉得应该是白色名单
字符串
yzckvree7#
如果你接收的是一个散列作为唯一的参数,为什么不把它作为一个示例变量呢?每当你需要一个值时,从哈希调用它。您可以保持示例变量名简短,以便可以轻松调用它。
字符串
如果
@p[:name]
对您来说仍然太长,那么您可以将proc保存为示例变量,并调用相关值,如@p.(:name)
。型
或者,另一种方法是定义一个调用哈希并应用键的方法。
型
如果要设置值,您可以定义一个setter方法,并进一步检查是否有无效的键。
型
fv2wmkja8#
本着@steenslag提案的精神,但也从模块中扩展了一些方法:
字符串