使用ruby在do块中分配类变量?

时间:2012-03-21 10:49:51

标签: ruby

我在ruby中遇到问题,即使我知道它在某种程度上是可能的,我似乎无法找到解决方案。我有一个类,我想在do块中为它分配一些变量,如下所示:

tester = Person.new
tester do
    :name => 'Andy'
    :example => 'Example'
end

puts "#{tester.name}:#{tester.example}" #Should output 'Andy:Example'

有没有人有任何想法?我为我可怕的解释方式道歉。我是Ruby的新手:)

6 个答案:

答案 0 :(得分:4)

这也有很好的旧yield self成语:

class Person 
  attr_accessor :name, :example

  def initialize 
    yield self if block_given?
  end
end

tester = Person.new do |p|
  p.name = 'Andy'
  p.example = 'Example'
end

puts "#{tester.name}:#{tester.example}" 

答案 1 :(得分:2)

你不能用Ruby这样做。您应该指定接收方

tester = Person.new
tester.name = "Andy"
tester.example = "Example"

<强> PS

以下是相关主题:

  

In Ruby, is there a way to accomplish what `with` does in Actionscript?

答案 2 :(得分:1)

可以这样设置:

tester = Person.new.tap do |person|
person.name = 'John'
end

答案 3 :(得分:1)

由于doing so will create a new local variable,无法在没有接收器的情况下调用名称以=结尾的方法。我建议允许将新值传递给您的读者方法:

class Person
  def initialize(&block)
    if block.arity.zero? then instance_eval &block
    else block.call self end
  end

  def name(new_name = nil)
    @name = new_name unless new_name.nil?
    @name
  end
end

现在你可以写:

Person.new do
  name 'Andy'
end

这种方法的唯一缺点是无法将属性设置回nil,因此请考虑提供传统的编写方法。

答案 4 :(得分:0)

do是指从迭代中产生的对象,它不允许您像上面那样编写代码。我建议采用不同的方法:

class Person
    attr_accessor :name, :example

    def assign(props = {})
        props.each{|prop, value| self.send("#{prop.to_s}=", value)}
        self
    end
end

x = Person.new
x.assign :name => "test", :example => "test_example"
=> #<Person:0x27a4760 @name="test", @example="test_example">

答案 5 :(得分:-1)

@ fl00r&#39的建议是正确的,或者你可以这样做,这与他最相似:

tester = Person.new
tester[:name] = "Andy"
tester[:example] = "Example"