From: Ilias Lazaridis Date: 2005-03-25T12:59:49+09:00 Subject: Re: [EVALUATION] - E03 - jamLang Evaluation Case Applied to Ruby Martin DeMello wrote: > Ilias Lazaridis wrote: > >>The above thread showed finally the need to split the evaluation down >>into smaller chunks. >> >>Here is a simple evaluation template (first part) which can be applied >>to the Ruby language: >> >>http://lazaridis.com/case/lang/index.html > > Okay, that's a neat bit of work. Here's a quick solution (ruby makes > most of this fairly trivial): > > # here's your basic talker class [...] preliminary draft: http://lazaridis.com/case/lang/ruby.html > # reflection > class Talker > > # simple > > def sayYourClassName > puts self.class.name # the 'self' is optional here > end omitting "self" (puts class.name) leads to an error > # objects know nothing about the variables that are bound to them > # (a variable name is not the name of the instance anyway). The > # closest you can come to the "name" of an object is it's object id, so... > def sayYourInstanceName > puts object_id # again, you could say self.object_id if you prefer > end ok > # advanced > > # caller returns a stack (array) of strings of the form > # file:linenumber in `method' > # so we extract the most recent one and parse the method name out > # code from PLEAC > def thisMethodName > caller[0] =~ /in `([^']+)'/ ? $1 : '(anonymous)'; > end I understand the concept. is there possibly a more direct solution available, with cleaner code and a stable/higher execution speed? > # string interpolation in action - the bit between the #{} can be > # any valid expression; to_s will be called on the result and > # interpolated into the string > def sayHelloAdvanced > puts "#{thisMethodName}: Hello World" > end ok > # expert > def sayYourClassDefinition > puts "Class:" > sayYourClassName puts "Class #{self.class.name}" >> Class Talker but puts "Class #{sayYourClassName}" >> Talker Class puts "Class " + sayYourClassName.to_s >> Talker Class why? > # %{} is another way to write a string literal #{} - inside strings %{} - outside of strings > # (looks neat for multiline strings) > # we use the standard 'inspect' method to print out arrays of > # method names in a ["meth1", "meth2", ...] format > puts %{ > Methods: > public: > #{public_methods.inspect} > protected > #{protected_methods.inspect} > private: > #{private_methods.inspect} > non-inherited: > #{(methods - self.class.superclass.instance_methods).inspect} > > Instance Variables: > #{instance_variables.inspect} > } Can I get somehow a more precise reflection of the class definition (output similar to the original class-def, excluding code)? > # note that the instance variables belong to the *instance*, not > # to the class, so they're not technically part of the class > # definition. the following code is illustrative: > # > # class A > # attr_accessor :foo, :bar # defines getters and setters > # end > # > # a = A.new > # p a.instance_variables # => [] > # a.foo = 10 > # p a.instance_variables # => ["@foo"] > # b = A.new > # p b.instance_variables # => [] > end ok > def sayYourClassCode > puts "Sadly, you cannot introspect the source code from within a program" > # though see http://rubyforge.org/projects/parsetree/ > # for a way to get at the parsed AST > end ok > end > > # testing it out > > if __FILE__ == $0 > talker.sayHelloAdvanced > talker.sayYourClassName > talker.sayYourClassDefinition > talker.sayYourClassCode > end > > Hope this helps. very much! thank you for your efforts. > martin .. -- http://lazaridis.com