# reflection
class Talker
# simple
def sayYourClassName
puts self.class.name # the 'self' is optional here
endomitting "self" (puts class.name) leads to an error
I checked this one myself, because it surprised me when you said it. You're right of course. I'm assuming it's because class is a method name and a Ruby keyword.
# 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)';
endI understand the concept.
is there possibly a more direct solution available, with cleaner code and a stable/higher execution speed?
Have you measured it and proven it too slow? Remember, premature optimization is the root of all evil in programming. ![]()
I'm not sure what you consider "clean", but getting rid of the ternary operator may make it a little more readable:
if caller[0] =~ /in `([^']+)'/ then $1 else '(anonymous)' end
# expert
def sayYourClassDefinition
puts "Class:"
sayYourClassNameputs "Class #{self.class.name}" >> Class Talker
but
puts "Class #{sayYourClassName}" >> Talker Class
puts "Class " + sayYourClassName.to_s >> Talker Classwhy?
In the first example, you're asking Ruby for the class name, which you add to a string that gets printed by the local call to puts. In the other two, you're calling a method that prints the class name immediately. Then the local puts prints "Class " and the return value from the method call, which isn't meaningful in this context.
# %{} is another way to write a string literal
#{} - inside strings
%{} - outside of strings
No, these are not equivalent. #{...} is for interpolating Ruby code inside a string. %{...} defined a double quoted string, without the quotes:
%{This is a string. I can use "quotes" in here. And #{"interpolate"} values.}
# (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)?
I don't believe so, no. Remember that a Ruby class can be reopened and definitions added to it. That means a class could be built up from many places.
Ruby does have a means to get it to store the source code it reads, but I don't believe that's what you were asking for.
James Edward Gray II
···
Begin forwarded message: