There's two ways you can go depending on if you want to be able to add
attributes that are NOT stored.
The easiest way is to use attr_accessor:
class ServiceProfile
attr_accessor :url, :username, :password, :certificate, :owner
def load_certificate()
@certificate.read
end
def call_service(&block)
end
end
class MyService < ServiceProfile
attr_accessor :extra
end
svc_profile = MyService.new
svc_profile.methods.sort.reverse.each { |meth|
if /^(.*)=$/ === meth
print "Enter #{$1.capitalize}: "
$stdout.flush
value = $stdin.gets.chomp
svc_profile.send(meth, value)
end
}
svc_profile.methods.sort.reverse.each { |meth|
if /^(.*)=$/ === meth
puts svc_profile.send($1)
end
}
The problem with this, however, is that you can't add any xxx=(x)
methods to the class without them being added to your storage system.
Instead, you could do:
class AutoPopulator
def self.attr_populator(*args)
attr_accessor(*args)
(@populators||=).concat(args)
end
def self.populators
populators =
populators = superclass.populators if superclass.respond_to?
:populators
populators += @populators if @populators
populators.uniq.collect {|x| x.to_s}
end
end
class ServiceProfile < AutoPopulator
attr_populator :url, :username, :password, :certificate, :owner
def load_certificate()
@certificate.read
end
def call_service(&block)
end
end
class MyService < ServiceProfile
attr_populator :extra
end
svc_profile = MyService.new
svc_profile.class.populators.each { |meth|
print "Enter #{meth.capitalize}: "
$stdout.flush
value = $stdin.gets.chomp
svc_profile.send("#{meth}=", value)
}
svc_profile.class.populators.each { |meth|
puts svc_profile.send(meth)
}
···
-----Original Message-----
From: wmwilson01@gmail.com [mailto:wmwilson01@gmail.com] On
Behalf Of swille
Sent: Friday, 28 October 2005 11:11 AM
To: ruby-talk ML
Subject: "Reflecting" on my self.n00bI'm admittedly quite a novice with programming. I'm sort of
playing around with some ideas, and I'm wondering if what I'm
doing is completely stupid, and if not, is there a better way
to do it? Also, is there any way that I could do some type
of type-ish validation on the data?Basically, I want to provide what I suppose would be abstract
class (?), which someone else could extend and add attributes
if they'd like. I'd like to be able to look into the class
and pick out the attributes to populate (which is the reason
for all of the sp_set & sp_get stuff). Basically, my thought
is to be able to provide a web interface at some point to
populate the needed data of a class, and then maybe
Marshal.dump the object to a database and call it later using
that data as config data essentially. I'm sure I could learn
a ton about this from reading Rails code, but there's so much
of it that I don't know where to look. Output and code
follows. Please feel free to tell me if this is dumb :O)Output:
Enter Username: name
Enter Url: url
Enter Extra: more
Enter Password: pass
Enter Owner: own
Enter Certificate: cert
name
url
more
pass
own
certCode:
<code>
class ServiceProfile
def initialize()
enddef sp_set_url(url)
@url = url
enddef sp_get_url()
@url
enddef sp_set_username(username)
@username = username
enddef sp_get_username()
@username
enddef sp_set_password(password)
@password = password
enddef sp_get_password()
@password
enddef sp_set_certificate(certificate)
@certificate = certificate
enddef sp_get_certificate()
@certificate
enddef sp_set_owner(owner)
@owner = owner
enddef sp_get_owner()
@owner
enddef load_certificate()
@certificate.read
enddef call_service(&block)
end
endclass MyService < ServiceProfile
def sp_set_extra(extra)
@extra = extra
enddef sp_get_extra()
@extra
end
endsvc_profile = MyService.new
set_re = Regexp.new('^sp_set_(\w+)')
get_re = Regexp.new('^sp_get_(\w+)')svc_profile.methods.sort.reverse.each { |meth|
if meth.match(set_re)
print "Enter #{Regexp.last_match(1).capitalize}: "
value = $stdin.gets.chomp
svc_profile.send(meth, value)
end
}svc_profile.methods.sort.reverse.each { |meth|
if meth.match(get_re)
puts svc_profile.send(meth)
end
}
</code>
#####################################################################################
This email has been scanned by MailMarshal, an email content filter.
#####################################################################################