From: Daniel Sheppard Date: 2005-10-28T14:42:52+09:00 Subject: Re: "Reflecting" on my self.n00b 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.n00b > > I'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 > cert > > Code: > > class ServiceProfile > def initialize() > end > > def sp_set_url(url) > @url = url > end > > def sp_get_url() > @url > end > > def sp_set_username(username) > @username = username > end > > def sp_get_username() > @username > end > > def sp_set_password(password) > @password = password > end > > def sp_get_password() > @password > end > > def sp_set_certificate(certificate) > @certificate = certificate > end > > def sp_get_certificate() > @certificate > end > > def sp_set_owner(owner) > @owner = owner > end > > def sp_get_owner() > @owner > end > > def load_certificate() > @certificate.read > end > > def call_service(&block) > end > end > > class MyService < ServiceProfile > def sp_set_extra(extra) > @extra = extra > end > > def sp_get_extra() > @extra > end > end > > svc_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 > } > > > > ##################################################################################### This email has been scanned by MailMarshal, an email content filter. #####################################################################################