2012-03-21 31 views
0

我在ruby中遇到了問題,即使我知道這是可能的,但我似乎無法找到解決方案。我有一個班級,我想給它分配一些變量,如下所示:使用ruby在do塊中分配類變量?

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

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

有沒有人有任何想法?我爲我可怕的解釋方式道歉。我是Ruby新手:)

回答

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}" 
+0

+1。 '如果block_given?'產生自我效能?:)。無論如何,這不是Ruby的工作方式。 Actionscript已經有了它的'with'方法,可以讓它在對象的「上下文」中工作。你不能在Ruby中做這種工作。 – fl00r 2012-03-21 11:58:46

+0

當然,但這是我最常見到的方式,以達到或多或少相同。除了'''也應該很容易實現:-) – 2012-03-21 12:05:22

+0

我相信幾乎所有的東西都可以用eval來實現;) – fl00r 2012-03-21 12:11:22

1

它可以設置這樣的:

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

@ fl00r的建議是正確的,或者你可以做這種方式是最相似的對他說:

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

-1,這甚至不是有效的Ruby。除非'Person'類指定了一個'[] ='方法,否則你會得到一個'NoMethodError'。 – 2012-03-21 11:41:58

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"> 
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 ,所以考慮提供一個傳統的寫作者方法。