CSC302 2011S, Class 35: Introspection and Reflection Overview: * Leftovers: Scoping * Introspection basics. * Application: Factory Methods. * Application: Dynamic Loading. * Application: Serializing. * Application: Profiling. Admin: * The Final: * If you would like to coordinate an alternate time, that's fine with me. * Multiple choice: You even get the questions (but not the choices) with me. * Reading for Friday: "Wikipedia on Garbage Collection", Skim sections 1 and 2 of Wilson on Garbage collection ftp://ftp.cs.utexas.edu/pub/garbage/gcsurvey.ps * Due to prereg and College committee work, I need folks to sign up for appointments. http://www.cs.grinnell.edu/~rebelsky/Schedule/signup.2011S.txt Signup via email. * CS Picnic: Friday, May 6, 2011. * Don't forget to vote on a t-shirt. EC: * EC for today's Integrating Digital Collections into the Liberal Arts College Curriculum, 4pm JRC 209. [academic] * EC for Poetry Convo Thursday. [academic] * EC for Thursday's Bites to Bits. [academic] * EC for Friday's CS table. [academic] * EC for Psychologist Candidate Talks, coming soon. [academic] * EC for field day (mac field or house field swap). [peer] * EC for Titular Head saturday [peer] * EC for chamber ensemble sunday [peer] Scoping (a contrived example) * Dynamic vs. static scoping * Dynamic is *usually* worse * Static scoping: The meaning of a variable is determined by its context in the static program texta * If you see an X in the program, you use the nearest enclosing declaration of X (local variable, parameter, etc) to figure out which X it is. * Dynamic scoping: The meaning of a variable is determined by its context in the dynamically executing program Start with a simple function: (lambda (x) ((lambda (f) (f x)) (lambda (y) (cons y y))) 'b) ((lambda (g x) ((lambda (f x) (f x)) g 'a)) (lambda (y) (cons x y)) 'b) vs. ((lambda (g x) ((lambda (f z) (f z)) g 'a)) (lambda (y) (cons x y)) 'b) Why we hate dynamic scoping: * If changing the name of a variable changes behavior, something seems wrong. * Hard to analyze. * Hard to define formally. Why do dynamic scoping? * McCarthy didn't realize that he was doing it. He just used the obvious implementation technique * Implementing static scoping is hard: It means that you need to somehow include "the enclosing environment" in every lambda expression you return. * People don't think hard enough. Introspection / Reflection * Programs can look inside themselves * Programs can reflect upon themselves Meaning * Given an object, find its class + Which is an object in type Class So, "hello".class is class String * Given a class object, + list all constructors (objects in class Constructor) + list all method (objects in class Method) + list all fields (objects in class Field) * Given an object in class Constructor, + Get a list of all the parameters + CALL IT Pseudo-java: "hello".class.getConstructor().construct(); * You can get a class given its name class.forName("String"); Java's additional thing: * Modify the class loader Why is this helpful? (What nails can we hit with this hammer?) (1) Factory methods Given some widget, fill in part of my GUI with N copies of that widget Theory (won't work) addLots (int n, Object class) for (i = 0; i < n; i++) self.add (new class()); Traditional factory method solution addLots (int n, ObjectFactory factory) for (i = 0; i < n; i++) self.add (factory.build()); class ButtonFactory implements ObjectFactory { Object build () { return new Button(); } } addLots (10, new ButtonFactory ()); But anonymous inner classes would be better. addLots (10, new ObjectFactory () { Object build { return new Button () }; }); Introspection provides another (clearer?) mechanism addLots (int n, String className) for (i = 0; i < n; i++) self.add (class.forName(className).getConstructor({}).construct()); --- Plug-ins for each filename in Plugins/*.class class.forName(filename).getMethod("run").call({}); -- Live Patching Provide an object, main, that does all the work main.checkStatusOfElecticalSystem(); main.addMorePower(); main.disconnectNonPayingCustomers(); Patching our system newMainClass = class.forName("Main.VERSION"); newmain = newMainClass.getConstructor({}).construct()); copyValues (main, newmain); main = newmain; --- Persistience * For each object * Get its class * Get its fields * Write the fields * And deal with sharing