7

是时候让它更短了:

class Foo
  attr_accessor :a, :b, :c, :d, :e

  def initialize(a, b, c, d, e)
    @a = a
    @b = b
    @c = c
    @d = d
    @e = e
  end
end

我们有 'attr_accessor' 来生成 getter 和 setter。

我们有什么可以通过属性生成初始化器吗?

4

5 回答 5

15

最简单的:

Foo = Struct.new( :a, :b, :c )

生成访问器和初始化器。您可以通过以下方式进一步自定义您的课程:

Foo = Struct.new( … ) do
  def some_method
    …
  end
end
于 2012-04-30T14:08:36.030 回答
2

我们可以创建这样的东西def_initializer

# Create a new Module-level method "def_initializer"
class Module
  def def_initializer(*args)
    self.class_eval <<END
      def initialize(#{args.join(", ")})
        #{args.map { |arg| "@#{arg} = #{arg}" }.join("\n")}
      end
END
  end
end

# Use it like this
class Foo
  attr_accessor   :a, :b, :c, :d
  def_initializer :a, :b, :c, :d

  def test
    puts a, b, c, d
  end
end

# Testing
Foo.new(1, 2, 3, 4).test

# Outputs:
# 1
# 2
# 3
# 4
于 2012-04-30T14:20:29.727 回答
1

您可以使用像构造函数这样的宝石。从描述:

声明式意味着通过将哈希传递给构造函数来定义对象属性,构造函数将设置相应的 ivars。

它很容易使用:

Class Foo
  constructor :a, :b, :c, :d, :e, :accessors => true
end

foo = Foo.new(:a => 'hello world', :b => 'b',:c => 'c', :d => 'd', :e => 'e')
puts foo.a # 'hello world'

如果您不希望使用访问器生成 ivars,则可以省略 :accessors => true

希望这会有所帮助/Salernost

于 2012-04-30T13:56:51.590 回答
0
class Foo
  class InvalidAttrbute < StandardError; end

  ACCESSORS = [:a, :b, :c, :d, :e]
  ACCESSORS.each{ |atr| attr_accessor atr }

  def initialize(args)
    args.each do |atr, val|
      raise InvalidAttrbute, "Invalid attribute for Foo class: #{atr}" unless ACCESSORS.include? atr
      instance_variable_set("@#{atr}", val)
    end
  end
end

foo = Foo.new(a: 1)
puts foo.a
#=> 1

foo = Foo.new(invalid: 1)
#=> Exception
于 2012-04-30T13:58:39.703 回答
0
class Module
  def initialize_with( *names )
    define_method :initialize do |*args|
      names.zip(args).each do |name,val|
        instance_variable_set :"@#{name}", val
      end
    end
  end
end
于 2012-04-30T14:06:07.480 回答