This morning session rocked my world. The afternoon session was better than yesterday but, for me, dragged a lot toward the end of the day.
I suspect that my less enthusiastic response to this class vice the Rails class has more to do with my significantly greater experience with Ruby the language than Rails the framework.
That said, I am still finding this class worthwhile to fill in the gaps in my understanding of Ruby to date.
Notes after the jump.
Ruby Object Model
NOTE: Parts of this portion of the class were presented to NoVaRUG in April by DT.
selfis the only way to access member variables.- Changing
selfis key to Ruby- On a method call
selfgets set to the receiver then the method is looked up- When defining a class
- This is universal to all implementations of Ruby
- Methods are stored on classes, data in objects. (Me: Nothing new there but important to note for below)
- When defining a method on an instance of a class, Ruby creates an anonymous class (aka “singleton class”, “eigenclass”, “virtual class”, and “metaclass”) to contain the new method and has it inherit from the original parent class.
- If reader == Java.WEENIE
- Ruby classes are executable code
- Ruby classes are Ruby Objects
- Me: Imagining your brain ’sploding.
Classes are executable code
puts "foo"class Stuff puts “bar” end
puts “blech”
… outputs:
foo bar blech
Classes are objects
puts "foo"class Stuff @v = 123 def self.get_v @v end end
puts Stuff.get_v puts “bar”
… outputs:
foo 123 bar
Matz says “don’t use @@ vars” and DT agrees.
- Instance variables looked up in
self Methods looked up in
self’s classMethod definition is different than method lookup
def foois defined in the current classdef obj.foois defined inobj’s singleton class
And the lightbulb goes off over my head
So this idiom that I’ve seen Giles use in his code somewhere doesn’t hurt my brain anymore:
something = "42"
class << something
def say_something
puts self
end
end
something.say_something
… will output 42. class << something changes the current Class to the singleton class of something.
Although the below example behaves the same way, it is less explicit in that it obscures what’s happening under the covers. The below example seems to define a method on something; it’s actually defining the method on something’s singleton class.
something = "42"
def something.say_something
puts self
end
something.say_something
Intrestingly, clone copies a singleton class as well but dup doesn’t.
Cute but not hugely relevant:
class Person < Struct.new(:name, :state)
# do stuff
end
… is legal — and a nifty way to save lines of code if you want to add methods to a Struct (or other expression that evals to a Class).
include- Points this object’s singleton class to the referred to module
- Does not copy methods from a module into a class
- So modules are actually shared
extendincludes into this object’s class’ singleton class.
Metaprogramming
instance_eval- Changes
selfto the receiver ofinstance_eval - Me: Cheeky way to call private methods on objects
- Changes
class_eval- Changes
selfto the receiver (a class) ofclass_eval - WTF is the current class? Still not clear on this — and DT was getting confused too! Oy vey!
- Changes
“Top level” methods are defined on a singleton instance of Object
to_sis redefined here as well to return “main”- Slide 167 explains the toplevel environment (although you’re not really in instance_eval)
Me: I actually found the Object Model discussion far more intense than playing with define_method — probably because I’m already pretty comfortable with meta/reflective programming from Java and having already used a fair bit of define_method and eval.
DT: Use of
method_missinginvolves two method calls so it’s a bit slower.initialize_copy- Define this to override the behavior of
dup— to possibly provide a deep copy
- Define this to override the behavior of
const_missing- Rails uses this to require files at runtime
const_getCan only call on one class at a time.
class Foo
class Bar
class Blech
end
end
end
c = self.class.constget “Foo”
c = c.constget “Bar”
c = c.const_get “Blech”
puts c
# >> Foo::Bar::Blech
The below example was in the Rails class but makes even more sense today thanks to our discussions of include and extend:
Hooks
included
Mixin a Module containing both instance methods and “class” methods
module Foo
def self.included(klass)
klass.extend ClassMethods
end
def foo
puts “foo”
end
module ClassMethods
def class_foo
puts “class foo”
end
end
end
class Person
include Foo
end
Person.new.foo
Person.class_foo
inheritedExplain why garbage collection in MRI ’sucks’ (Me: Certain individuals I know, who shall remain nameless, *cough*Toby DiPasquale*cough* have commented on this)
- DT
- Typically not a problem
- However, if you have a LOT of loose objects (100s of thousands… try creating a String by concat’ing lots of Strings together).
- Had a program that did this. Instead of concat’ing several times, accumulated the Strings in an Array and created it at the end
- Performance went from two minutes to one second
- JRuby uses the JVM garbage collector (GOOD)
- Rubinius is better
- 1.9 is better
… make it fast
- CF rant about maintainability. No argument here.
- benchmark.rb
Benchmark#bmbm(great name) does a rehersal run first and then a real run
- For socket code
- Socket::do_not_reverse_lookup = true
- YAML
YAML#dump== slow
update_page in Rails
- Calling in more than 15 times for a single page will cause a noticeable slowdown
ObjectSpace
- Iterate through objects and ue
Marshal#dumpto determine amount of memory taken up by a certain class
- Iterate through objects and ue
To speed things up
- C (and other) extensions
- DL (dynamic linking) — link a library at runtime and use it directly
- Requires mapping C function calls (and structs if used) to Ruby objects
- Slide 115-6
Some lecture on good ol’ fashioned CS: O(n), O(n^2), and avoiding stupid loops
- Wow, DT cites Sedgewick (Me: I learned wth Corman)
- Now CF is talking about eager loading and caching as a way of optimizing runtime.
- This afternoon just seems like… common sense programming/software engineering/computer science that every student in here ought to have.
- “Memoization”
- Caching values of expensive operations for later re-use
- There are some gems/libraries out there to keep code cleaner
- Basically just the use of the
||=idiom
Exercise Playing with memoization Fibonacci to run super-fast
Library Organization
- Discussion of setup.rb and RubyGems
- Having written a few gems and installed who knows how many, this section of the class is mind-numbing
- Dr. Nic’s NewGem gem essentially obviates much of this section of the class. Just use NewGem, write your own little gem, play with it, and that will teach you plenty.


0 comments ↓
There are no comments yet...Kick things off by filling out the form below.
Leave a Comment