I'm having a problem in ruby and I can't seem to find the solution even though I know it's somehow possible. I have a class and I want to assign some variables to it in a do block like so:
tester = Person.new
tester do
:name => 'Andy'
:example => 'Example'
end
puts "#{tester.name}:#{tester.example}" #Should output 'Andy:Example'
Has anyone got any ideas? I apologise for my terrible way of explaining. I'm new to Ruby :)
There's the good old yield self
idiom for that too:
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}"
You can't do it in Ruby this way. You should specify reciever
tester = Person.new
tester.name = "Andy"
tester.example = "Example"
PS
Here is related topic:
In Ruby, is there a way to accomplish what `with` does in Actionscript?
It may be set like this:
tester = Person.new.tap do |person|
person.name = 'John'
end
It is not possible to call a method whose name ends in =
without a receiver, because doing so will create a new local variable . I suggest allowing new values to be passed to your reader methods:
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
Now you can write:
Person.new do
name 'Andy'
end
The only drawback to this approach is that it is impossible to set the attribute back to nil
, so consider providing a conventional writer method as well.
do
is refers to the object yielded from an iteration, which doesn't allow you to write code as above. I'd suggest a different approach:
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">
@fl00r's suggestion is right or you may do it this way which is most similar to him:
tester = Person.new
tester[:name] = "Andy"
tester[:example] = "Example"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.