Reputation: 305
module Framework
class CreateTableDefinition
attr_accessor :host, :username, :password
end
end
def create_table(table_name)
obj = Framework::CreateTableDefinition.new
yield(obj) if block_given?
end
create_table :users do |config|
config.host :localhost
end
And here is the error I get
-:13:in `block in <main>': wrong number of arguments (1 for 0) (ArgumentError)
from -:9:in `create_table'
from -:12:in `<main>'
If I change the code to
config.host = :localhost
it works fine. But what I want is to work as described above config.host :localhost
Upvotes: 0
Views: 175
Reputation: 44675
You missed assignment:
config.host = :localhost
If you want to get rid of assignments, you need to define setter methods without =
at the end. This might generate quote a lot of code, so I would rather go with some meta-programming (because it's fun!)
class MyConfigClass
def self.attributes(*args)
args.each do |attr|
define_method attr do |value|
@attributes[attr] = value
end
end
end
def initialize
@attributes = {}
end
def get(attr)
@attributes[attr]
end
end
class CreateTableDefinition < MyConfigClass
attributes :host, :username, :password
end
c = CreateTableDefinition.new
c.host :localhost
c.get(:host) #=> :localhost
Upvotes: 2
Reputation: 1851
Try manually making a method that does what you want instead of using the attr_accessor
shortcut.
class CreateTableDefinition
attr_accessor :username, :password
def host(sym)
@host = sym
end
def get_host
@host
end
end
If you don't like the idea of writing those methods for every attribute, look into writing your own helper, something like attr_rails_like
, and mix it in to the Class
object. This article might be helpful.
Upvotes: 0