B S*_*ven 29 ruby object new-operator ruby-1.9.3
class Foo
attr_accessor :name, :age, :email, :gender, :height
def initalize params
@name = params[:name]
@age = params[:age]
@email = params[:email]
.
.
.
end
Run Code Online (Sandbox Code Playgroud)
这似乎是一种愚蠢的做法.在Ruby中初始化对象的更好/更惯用的方法是什么?
Ruby 1.9.3
Jos*_*eek 41
您可以迭代密钥并调用setter.我更喜欢这个,因为如果你传递了一个无效的密钥,它会被捕获.
class Foo
attr_accessor :name, :age, :email, :gender, :height
def initialize params = {}
params.each { |key, value| send "#{key}=", value }
end
end
foo = Foo.new name: 'Josh', age: 456
foo.name # => "Josh"
foo.age # => 456
foo.email # => nil
Run Code Online (Sandbox Code Playgroud)
Zac*_*emp 17
def initialize(params)
params.each do |key, value|
instance_variable_set("@#{key}", value)
end
end
Run Code Online (Sandbox Code Playgroud)
Vad*_*rov 12
通过一些概括来充分利用Joshua Cheek的答案
module Initializable
def initialize(params = {})
params.each do |key, value|
setter = "#{key}="
send(setter, value) if respond_to?(setter.to_sym, false)
end
end
end
class Foo
include Initializable
attr_accessor :name, :age, :email, :gender, :height
end
Foo.new name: 'Josh', age: 456
=> #<Foo:0x007fdeac02ecb0 @name="Josh", @age=456>
Run Code Online (Sandbox Code Playgroud)
注意如果已经使用了初始化混合,我们需要自定义初始化,我们只需要调用super:
class Foo
include Initializable
attr_accessor :name, :age, :email, :gender, :height, :handler
def initialize(*)
super
self.handler = "#{self.name} #{self.age}"
end
end
Foo.new name: 'Josh', age: 45
=> #<Foo:0x007fe94c0446f0 @name="Josh", @age=45, @handler="Josh 45">
Run Code Online (Sandbox Code Playgroud)
Foo = Struct.new(:name, :age, :email, :gender, :height)
Run Code Online (Sandbox Code Playgroud)
这对于一个功能齐全的课程来说足够了.演示:
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
Run Code Online (Sandbox Code Playgroud)