Summarized using AI

The Well-Grounded Nuby

David A. Black • September 29, 2011 • New Orleans, Louisiana • Talk

In the talk titled "The Well-Grounded Nuby," David A. Black presents an insightful examination of key features and characteristics of Ruby programming language, particularly addressing common challenges faced by newcomers. Utilizing his extensive experience, Black outlines seven points of confusion that can hinder understanding, aiming to enhance both comprehension and coding skills for learners and mentors alike.

Key Points Discussed:
- Everything Evaluates to an Object: Black clarifies that although many elements in Ruby are not objects per se, every expression evaluates to an object, emphasizing that even programming constructs and flow-control statements return values, such as nil.
- Sending Messages to Objects: He explains that Ruby operates on the principle of sending messages to objects, using syntax that may obscure this underlying behavior. He illustrates this with examples of arithmetic operations and method calls that are essentially message passing.
- Distinction Between Messages and Methods: Black emphasizes the importance of differentiating between messaging and method calling, clarifying that methods exist within classes and modules rather than being properties of the object itself.
- Understanding self: The concept of self is highlighted, detailing how it changes context based on where it’s accessed, including implications for instance variables, making it crucial for new Rubyists to grasp.
- Variables as References: The talk explains how variables in Ruby contain references to objects, which can lead to confusion when multiple variables reference the same object.
- Classes and Modules are Objects: Black shares that classes and modules are indeed objects, capable of holding state and possessing instance variables, which underlines their role in Ruby’s object-oriented model.
- Truthiness in Ruby: Finally, the speaker demystifies how Ruby evaluates truthiness, noting that only nil and false are considered falsey, contrasting with other languages that treat values like zero differently.

Throughout his presentation, Black employs code examples and whimsical scenarios to illustrate his points, ensuring a deeper understanding of Ruby’s fundamentals. The emphasis on common pitfalls, such as method scope and variable referencing, serves as a guide for effective coding practices. The conclusion encourages participants to leverage these insights for personal growth and when mentoring others in their Ruby journey.

The Well-Grounded Nuby
David A. Black • New Orleans, Louisiana • Talk

Date: September 29, 2011
Published: December 12, 2011
Announced: unknown

An examination of a large handful of features and characteristics of Ruby that, once understood, provide a solid foundation for continued learning and/or mentoring

RubyConf 2011

00:00:16.410 come to the well grounded newbie advice for Ruby newcomers and their mentors I
00:00:23.590 know that not all of you are Ruby newcomers in fact I see some reasonably seasoned Ruby programmers in the room
00:00:31.590 but as you'll see this is advice partly for newbies and partly for people who
00:00:37.239 might have occasion in turn to advise or mentor newcomers to Ruby just a couple
00:00:44.650 of words about me I started using Ruby in 2000 which was when the pickaxe book
00:00:50.290 came out the book programming Ruby by Dave Thomas and Andy hunt I sort of
00:00:55.300 stumbled on the book literally well you know manually anyway at a bookstore
00:01:00.449 right after it came out and I've been hooked on Ruby ever since I'm one of the
00:01:05.680 directors and founders of Ruby central and we're the parent organization of this event as well as railsconf and
00:01:12.640 other projects what are we going to do
00:01:17.710 today well we're going to learn some what I consider major common points of
00:01:22.930 confusion essentially what I've done here is to choose and this is a purely subjective choice but i have chosen
00:01:30.359 points that i think because I've seen it happen over and over again I think are particularly either difficult or tricky
00:01:38.799 or in some way kind of hard to hard to
00:01:44.469 grasp particularly for newcomers so we're going to look at some of these points and hopefully this will improve
00:01:51.579 both your ability to understand code and to write code because you'll see exactly what's going on in some of these cases
00:01:58.950 we're going to look at seven points again this is a purely subjective choice
00:02:04.679 seven points that I think are common stumbling blocks and i should add it's
00:02:10.539 not just for absolute newcomers to Ruby this is my choice of the seven points is
00:02:15.580 based on years of training rubyists including people who are not necessarily
00:02:21.760 complete beginners but these are things that I've seen people kind of have trouble with again and again and we'll
00:02:29.170 look at how these particular seven points can help you understand Ruby questions throughout if you have
00:02:34.840 questions just go ahead and and raise your hand and we may have some time at
00:02:40.630 the end to but if you you know as we go along if you have questions that's fine i'll try to accommodate them all right
00:02:46.630 so we're going on this this little trek through seven points custom chosen by me
00:02:52.030 to help you get a handle on some of the tricky things in Ruby okay every
00:02:58.270 expression evaluates to an object you will sometimes hear people say of Ruby
00:03:03.910 everything is an object everything is not an object for example an if
00:03:10.959 statement is not an object an argument list is not itself an object it's a syntactic construct keywords are not
00:03:18.550 objects so there are things in Ruby sort of peppered throughout the code that are
00:03:23.709 not themselves objects you can point to something and say that that isn't an object it's a keyword or whatever but
00:03:30.480 everything does evaluate to an object including things like if statements
00:03:36.310 method definitions class definitions so everything evaluates or reduces to an
00:03:42.820 object and we're pretty used to this with you know with if you just type in
00:03:48.220 like the number 10 it evaluates to the number 10 but here's a couple of of ones
00:03:54.430 that you might come across and not not know exactly what to expect for example
00:03:59.620 an if staff failed if statement always returns nil so if you say if something
00:04:06.100 and it's not true and there's no branch of the if that returns true or that that
00:04:11.170 that evaluates the true the entire if statement those three lines evaluate to
00:04:17.680 nil so everything reduces to an object an if statement reduces to an object in
00:04:23.440 this case it reduces to the object nil and it does it never reaches that middle
00:04:28.540 line that with that string not reach so this is a failed if statement on the put
00:04:35.140 s or puts method also evaluates to nil and sometimes again especially if you're not used to
00:04:42.040 IRB which has this read eval print loop going IRB is very literal if I say put s
00:04:48.970 hello it will obediently print the word hello but the entire operation the
00:04:55.780 actual call to the method put s returns nil and put us all these returns nil
00:05:02.800 that's it does not return the string that it prints it prints the string is a kind of side effect and it returns nil
00:05:09.460 that's why you get in IRB you get the string printed out but then you get nil
00:05:14.919 as the return value the evaluation of the entire statement empty class
00:05:22.630 definitions now this is a little bit arcane there's not too many use cases
00:05:27.699 where you care what a class definition evaluates to you care about defining a
00:05:33.160 class you don't necessarily care what the class definition ends up reducing to but it's there there are a couple of use
00:05:40.990 cases and it's I think just instructive to know that a class definition does
00:05:46.060 have a value an empty class definition evaluates to nil so if i say class c and
00:05:52.349 that's an empty class definition it's nil if you happen to have an object
00:05:57.580 other than nil in your as the last value in your class definition the entire
00:06:02.680 definition will evaluate to that object so the value of those three lines at the
00:06:08.169 bottom class see some value in a class definition end the value of that statement is the string some value in a
00:06:15.639 class definition so again everything reduces to an object and went when in
00:06:22.090 doubt if you're sort of wondering why something's nil or why something is until for that matter think about the
00:06:28.449 the literal kind of looking at what the statement or expression reduces to all
00:06:35.979 right point number two it's all about sending messages to objects this is not
00:06:42.070 an obscure point this is kind of the lifeblood of Ruby but it's worth noting
00:06:48.490 that and I think this is one of the kind of really interesting and cool character teristics of Ruby that it's all about
00:06:55.770 sending messages to objects even when it doesn't look like it is so for example
00:07:02.130 you have well you have messages that come after dots those are kind of the
00:07:07.440 you know the sort of bread and butter ABC dot up case that's sort of the the the most kind of canonical way to send a
00:07:15.750 message to an object you put a dot after it and then you put a message in this case the message up case however in fix
00:07:23.610 and you know unary operators are usually also sending messages and I'll show some
00:07:31.110 examples to square brackets are a message case statements also end up
00:07:37.259 sending messages to objects so let's look at a couple of these for example 3
00:07:42.330 plus 2 in Ruby that in fix plus sign is actually a method call it's actually
00:07:49.070 three essentially it's three dot plus with the with the argument too so you're
00:07:58.110 sending the message plus sign to the object three with the argument to Ruby
00:08:04.650 very nicely allows you to write it as an infix operator but you're literally calling a method whose name is plus sign
00:08:13.789 the same thing for most of the other arithmetic operators including star and
00:08:19.949 division and so forth square brackets are another one if you look at a sub 2 I
00:08:26.880 use the word sub for square brackets I think that's very old-school i'm not sure but that's what i mean by sub is a
00:08:32.789 square brackets to the object a in this case has a method whose name is a pair
00:08:41.370 of square brackets and i'm calling that method with the argument too so again i'm sending a message to an object even
00:08:48.540 though Ruby because of it's just it's what it allows my way of syntactic sugar
00:08:54.230 so to speak ruby has it it looks like
00:09:00.360 syntax but it's actually calling a method in this case the square bracket method
00:09:06.060 interestingly even the unary plus the plus sign in front of an object can
00:09:11.130 actually be defined through this method called + @ sign now this is a kind of bogus example because you can't actually
00:09:18.060 call it with a dot so this is more just to give you kind of an x-ray of the fact that the behavior of an object in the
00:09:25.290 face of a unary plot a preceding plus sign will actually be determined by that
00:09:31.350 method for example let's see if can we
00:09:36.960 get this is an IRB session in a slightly
00:09:43.760 malformed terminal well if I think you'll be able to see this if I say
00:09:50.070 something like class person what I feel
00:09:57.330 like the indentation is weird here let's let's try this again okay class person
00:10:06.500 at row reader name this is just a very
00:10:13.100 simple will say initialize name equals name and now I'm going to define plus at
00:10:23.490 whoops + @ sign and i'm just going to define it as name dot up case and you'll
00:10:30.540 see this just allows us to kind of follow the the dye through the bloodstream so to speak so now i'm going
00:10:36.840 to go david equals person new hope this
00:10:42.030 is just going to run off the screen Paul what is how clever of me just invented
00:10:52.320 the mouse okay David equals person new
00:11:00.560 and will give me a name now this is you
00:11:06.420 know this is just sort of whimsical example but if I now say plus David I get my name in uppercase right in other
00:11:15.210 words i have defined the logic for the unary plus sign and it behind the scenes
00:11:22.590 involves sending a message calling a method and coming up with the result of that alright so operators are mostly
00:11:34.110 methods and this is actually just an example of of the regular plus sign in
00:11:40.200 this case I hope it's not too small but I mean you can you know sort of experiment with this to on your own this
00:11:46.470 is another person class it has an inner class called couple the idea here is that when you have a couple of people
00:11:53.070 which you achieve through a plus sign you get if you look at where it says def
00:11:58.980 to s basically the string representation of a couple is the two names joined by
00:12:04.770 the word and so if I say John equals person new marshal equals person new
00:12:09.960 give them the appropriate names then I say couple equals John plus Marcia what
00:12:16.050 happens is the plus method gets called and it returns a new couple and then if I print the couple it it falls back on
00:12:23.850 the 2's method for couples and at Prince John and Marcia so basically you can
00:12:29.040 again this is sort of whimsical example as most of them are as you'll see but you can you can basically do what you
00:12:36.420 want with the the plus logic but again it's always calling a method and and by
00:12:41.610 the same token you can sort of hook into it by defining that method yes
00:12:48.920 right that's just the name of the mat that's the name of the sort of the hook
00:12:56.310 you have to define so yeah I mean if you define just plus then you get the infix
00:13:03.120 operator syntax if you define the plus at it gives you the unary plus behavior
00:13:15.980 okay another I think really prime example of a case where where Ruby looks
00:13:22.230 like it isn't sending messages to objects but it actually is is the case
00:13:27.450 statement now if you look on the column on the left and just ignore the rest of the moment I have case some string which
00:13:35.160 is whatever when ABC which means if this if the string is the string ABC do you
00:13:41.430 know such and such data when regular expression d e f if the string matches d
00:13:46.740 e f do something else and case statements in Ruby are governed or
00:13:53.460 engineered by this method whose name is three equal signs now or the threequel
00:14:00.960 operator if you will what actually happens under the hood when I say when
00:14:08.660 ABC I have a when clause what's actually happening in terms of what Ruby is doing
00:14:15.750 is it's saying if ABC three equal signs some string right if I say case some
00:14:25.470 string when ABC I'm really saying if ABC three equal some string and that in turn
00:14:34.380 is really just syntactic sugar for this there is a method called three equal
00:14:42.720 signs and if like the plus sign if you use it as an infix operator you're
00:14:49.590 actually calling a method now this middle one where you use it as an infix operator that's sort of a you know kind
00:14:55.890 of hypothetical you know you don't we necessarily see that I mean when you do the case statement this is all you
00:15:01.270 know wrapped in layers of syntactic sugar on top of sugar but what's really going on is that I'm calling the
00:15:08.020 threequel method the three equal sign method on the string ABC with the argument of my my case expression some
00:15:15.940 string now what this means again is that you can also roll your own in other
00:15:23.050 words if you want to define your own case behavior how are my objects going to fare in the face of a case statement
00:15:29.410 well here what I've done is again the good old class person I've now got name
00:15:36.130 and social security number so SSN and up
00:15:42.040 there in red I've defined my three equal method and what it basically says is the
00:15:47.110 threequel method returns true if my social security number is the same as
00:15:52.990 the social security number of the argument to the threequel method so what
00:15:58.540 happens then i create david with a number Joe with a number and mystery
00:16:03.790 person with as it happens david's number so now we're going to see which which person is the mystery person well when
00:16:11.350 Joe foot as its Joe when David presents David and again this is based on Joe
00:16:19.450 threequel mystery and David threequel mystery and of course it turns out to be David so you can actually govern the
00:16:27.880 behavior of your objects in case statements by hooking into this three equal method you never actually other
00:16:33.760 than defining it you never 4k statements at least you never actually have to type it it just happens automatically but
00:16:41.020 that's kind of the underpinning of of the the case behavior alright so we see
00:16:50.320 messages are being sent to objects even where it doesn't necessarily look like they are as in case statements and in
00:16:56.230 fix operators it is also true and this is our third point that objects resolve
00:17:03.130 messages into methods now I am splitting hairs here i am i am kind
00:17:12.980 of putting in a wedge between the message and the method in normal
00:17:20.329 conversation right we talk about we send messages to objects where we say you know I I called the up case method on
00:17:27.319 this object or I sent the message up case to the subject probably more often say I called the up case method on this
00:17:32.870 object method and message are you know there's a little bit of fluidity just in
00:17:39.200 kind of how we use the most of the time but I'm again i'm driving a wedge through them i want to be be clear about
00:17:44.960 the difference between sending the message and calling the method my take
00:17:51.409 on this and I've actually gotten in trouble on a mailing list for saying it this way but I've thought about it and
00:17:57.470 I've decided I'm sticking to it that objects do not have methods now it is
00:18:03.529 sort of a half-truth I mean you can say yes a string has an up case method but what I mean by this when I say objects
00:18:09.950 do not have methods what I mean is that the method itself does not live in the
00:18:15.470 string object the method itself every method lives in a class or a module
00:18:22.909 there are no exceptions to that every methods are defining classes or modules they're not defined Eve even a method
00:18:30.470 that you define on an individual basis just for one object that method and you
00:18:36.169 can do that in Ruby defining singleton methods that method still lives in a class it lives in what we call the
00:18:42.620 singles in class of the object so every method even if it's just a method on one
00:18:48.470 object every method lives in a class or module so object that's what I mean when I say objects do not have methods
00:18:54.260 objects have intelligence you send a message to an object the object has the
00:19:01.159 intelligence to search through a predetermined path of classes and
00:19:06.860 modules to find a method that corresponds to the meth message so I
00:19:13.429 send the message up case to a string the string has a search path where
00:19:19.140 it looks for a method whose name is up case and when it finds it it executes it
00:19:24.300 if it doesn't find it you get a method missing error this is a diagram actually
00:19:29.910 from my book the well-grounded rubios and what's going on here is if you look
00:19:36.150 at the bottom we create a new object and send it the message X now this just
00:19:41.460 gives you a sense of where an object looks for methods we in this case we're
00:19:46.740 looking for a method called X going to actually not find it according to this because it's not actually defined the
00:19:53.640 first place it looks is actually in what I refer to as the singleton class of the object which is really just a storehouse
00:20:01.260 for methods that belong only to this object and in fact singleton classes are
00:20:07.740 only created sort of on-demand objects just for efficiency reasons objects
00:20:12.870 don't even have a singleton method unless you are sorry singleton class unless you define a singleton method or
00:20:19.110 open the class explicitly as I've done here now the singleton class this this
00:20:24.600 notation class arrow arrow object that actually opens up the singleton class of
00:20:30.030 the object and what i've done here is i've included a module called n what that means is in its as the object
00:20:36.510 searches for this x method after it looks in its singleton class it will look in any modules that are included in
00:20:43.560 that class so it goes off and makes us what i think of its kind of side trip to
00:20:49.110 the module and does not find a method called X comes back to the main track
00:20:54.660 and goes up and now it's at the class D which is the class of this object so
00:21:00.510 it's now looking in its in its original class and saying you know is there an X method well no there isn't ok how about
00:21:07.770 any modules that are included in this class well there's a module called em that's included in this class so let's
00:21:14.070 go look at em is there an X method no so back we go and up to the superclass of D
00:21:20.610 notice that D inherits from see we look in C we find that there's no x.x method
00:21:28.410 and it actually would go beyond that once you hit sort of the top your class tree it would then go up to
00:21:34.600 the object class the the kernel module
00:21:39.730 which is included in object and then finally up to the basic object class which is really the top of the tree and
00:21:46.450 if it doesn't find it there it's it's it's failed and you get a method missing error this is just a little bit of sort
00:21:58.929 of showing the look up in action again the person class with the name accessor
00:22:05.140 I create a person object named David I'm now going to create a module called
00:22:10.570 vocal which simply has a method called talk and it's it's a little bit tightly
00:22:19.059 coupled with the person class admittedly it depends on the name method but we'll
00:22:24.370 let me will give me a free ride on that one how's that so we have a method called talk which basically just says
00:22:30.580 your name now a class person I include the vocal module that means if I say put
00:22:37.059 s David talk David the object David this person object now has access to a talk
00:22:44.440 method and notice one important thing here is that when i created David David
00:22:50.200 did at that time did not have a talk method because there's no talk method in the person class but even after i've
00:22:58.510 created the person object i can include a module in the person class and even the pre existing objects will be able to
00:23:07.090 find the methods that are in that module it's all about what the object nose at
00:23:12.549 the moment that you send it a message so I send it the message talk and at that
00:23:17.919 moment all it cares about is is there such a method in my class is there such
00:23:24.220 a method in a module included in my class I guess there is because it includes vocal so that's a good a good
00:23:32.490 illustration of the fact that all objects care about is what is the state
00:23:37.780 of things at the time that you send on the message all right now I have a second module
00:23:44.560 called loud and what this does is it
00:23:50.350 actually called super which suit what super does is super walks up this path
00:23:57.160 of method searching and finds a previous definition and execute that so it's
00:24:05.740 going to walk up the up the class and module path looking for a method called talk and it's going to find it out sorry
00:24:14.560 I should mention I then do class person include loud so now when I say put s
00:24:20.140 David talk it says hi my name is David but in capital letters with exclamation
00:24:26.290 points because now it's loud now one thing here this is a little bit of a contrived example well most of them are
00:24:33.160 this in this talk but one thing that this illustrates is the order of
00:24:38.970 execution when you include more than one module the object when I say put s David
00:24:46.570 talk it actually finds the talk in the loud module and the loud module finds
00:24:53.650 the talk in the vocal module basically when you're when the object is doing this search through classes and modules
00:24:59.890 when it's looking at modules it goes in reverse order of inclusion so the most
00:25:05.230 recently included module will be the first in the search path and then the
00:25:11.740 neck you know that if you call if it doesn't find it there it goes to the next one and so forth or in this case
00:25:17.680 super takes it to the next one so there's a very sort of you know strict
00:25:23.380 set of rules governing the lookup the method look up process and then this one
00:25:31.240 is just a of extend in this case what I've done is I've said module quiet
00:25:38.290 define talk and this is you know multiple parentheses just to show you
00:25:43.390 how quiet it is and what I do here is I take the David object and I extend it
00:25:48.700 with quiet and when you extend your it's similar to including a module except
00:25:54.790 it's on a per object basis so what I'm saying is you know most person objects are going to
00:26:00.320 talk loud at this point but this one person object I'm extending with the quiet module so now when I say David
00:26:06.740 talk I get the result of the of the quiet the quiet version of talking so
00:26:14.450 basically you can you can manipulate you know what where the object is going to find the method where along the path
00:26:22.730 it's going to either find it or fail to find it and it's good to know again that
00:26:28.130 objects are looking along a path of modules and classes the object is not
00:26:33.920 itself sort of possess the method all
00:26:40.610 right classes and modules are objects he
00:26:45.860 answered a 75-percent of all questions about Ruby is because classes are objects mean and it's really remarkably
00:26:55.940 true oh there's a lot of a lot of things that get clarified when you when you
00:27:01.850 totally grasp this idea that classes are objects because classes and modules are
00:27:07.400 objects and classes sort of our modules actually close the class class is a
00:27:12.560 subclass of the module class so classes and modules are very very similar objects in not in every way but in a lot
00:27:19.880 of ways but classes and modules are objects therefore you can send them messages right just like you can with
00:27:26.720 any other object you can put them in collections you can assign them to local variables perhaps one that that causes
00:27:34.190 some confusion is the fact that a class can actually have its own instance
00:27:40.040 variables every object in ruby has at least potentially a stash of instance
00:27:46.790 variables that represent the private state of that object well since a class is an object it can have its own
00:27:54.290 instance variables it can have its own private state it's not something you do
00:27:59.540 every day you don't necessarily you know always have a need to give instance
00:28:05.270 variables to class objects but it's good to understand you can because the class itself is an
00:28:12.540 object and therefore it has you know sort of all of the the rights and privileges connected with being an
00:28:19.140 object like being able to have its own its own its own instance variables here
00:28:29.250 is just again a little code illustration i have a class person i assign it to a
00:28:35.400 local variable this is just to you know make it clear that it's the object that
00:28:40.650 matters it's not the fact that it's referenced in a constant like person you
00:28:45.840 can put it you can bind it to any identifier I say David equals my class
00:28:51.360 new so even though my class does not begin with a capital letter it the object it evaluates to is a class and
00:28:58.920 therefore i can call new on it the commented out line is if i say class myclass that doesn't work because the
00:29:06.360 class keyword does expect a constant so you can't just drop in a local variable
00:29:12.510 in that position however you can do something like my class class eval and
00:29:18.120 what that will do is it will put you into a class definition block that's based on that class and then you can
00:29:25.440 proceed to define methods and so on so there's as usual there's ways to sort of you know related alternate techniques
00:29:32.220 for doing stuff that that at first it might seem you're not allowed to do all
00:29:40.020 right so classes or objects is is an important one and worth sort of playing around with point number five there's
00:29:48.990 always a self now self plays several
00:29:56.100 different roles whatever object is self at a given moment and there's always exactly one it's the default receiver of
00:30:03.120 messages so if you if you're in a context where where a string is self
00:30:09.770 then if you just say like down case and not string dot down case or even self
00:30:18.060 case a sort of bear word like that Ruby well first it will try to resolve it as
00:30:24.050 a local variable and if it fails it will try to resolve it as a method being called on self so self is a default
00:30:31.370 receiver of messages when you when you don't specify a receiver and you don't have a dot thank you they like that self
00:30:43.430 is the owner of all instance variables now this is a really important one and this one this leads to a lot of
00:30:49.940 confusion and it's worth really internalizing this every time you look
00:30:55.040 at ruby code and you see an instance variable at whatever that instance
00:31:00.800 variable without exception belongs to whatever self is at the moment that it's
00:31:08.180 being executed every instance variable belongs to self so if for example one of
00:31:18.500 my favorite examples actually if I say
00:31:28.060 well let's just say Class C it doesn't much matter
00:31:33.510 now look what I've done here I've created an instance variable this also
00:31:38.520 connects up with the point about classes owning their own instance variables so that instance variable belongs to self
00:31:45.260 now what is what exactly is self at this moment well if we evaluate self we find
00:31:52.560 itself is the class C so that instance variable let's go back in here we'll
00:32:00.840 just I don't actually have to do it again but now if I say def misleading
00:32:08.730 method now here's what's going to happen
00:32:14.880 I say see new and i'm going to say c misleading method anyone want to walk
00:32:24.660 into my little trap what's it gonna print it's so mean of me I really
00:32:30.360 shouldn't do well let's just say if you glance at it you could you could easily
00:32:36.030 and many people have assumed that it will print one because look you've got you know you're you're assigning to an
00:32:42.000 instance variable VAR e equals lat bar equals 1 2 lines later you're printing an instance variable the reason it
00:32:48.840 doesn't print 18 prints nil the reason is that self-- has changed and that
00:32:59.790 second line where I say at bar equals oneself is the class object two lines
00:33:05.340 later because I'm in a method definition self is an instance of this class so it
00:33:13.350 is a different object yes it is an instance of the class that was self before but they are to the class c and
00:33:22.050 the seedot new object are two unrelated other than the fact that one is an instance of the other they're unrelated
00:33:28.440 they're not the same object they do not share instance variables so what's
00:33:34.170 happening is that Ruby is being very literal and saying every instance variable belongs to self and as far as
00:33:40.350 its concerned I'd never initialized the one that's on line 19 right that's that
00:33:46.080 defaults to nil I actually didn't did not initialize that particular variable the value of
00:33:54.630 self changes it will flip to something different in a class definition where it becomes the class itself in a method
00:34:01.950 definition and again this is sort of echoes the example i just showed where
00:34:07.460 itself becomes the object that will call the method in instance eval it becomes
00:34:15.150 the receiver of instance about instance eval is basically a way to flip self to
00:34:20.280 be something else if you want if you want to to change self for the duration
00:34:25.560 of a code block you use instance of Al and the object on which you call instance of al becomes self for that
00:34:31.530 code block and in class of alat becomes the class and module so there's there's you know place is kind of fairly you
00:34:39.240 know fairly small number of places but important to to grasp where self will actually change or flip to another
00:34:46.950 object this is just kind of tracing self
00:34:53.970 at different points one thing to note is that well self in the class definition
00:35:00.570 body comes out as person self in the instance method comes out as the person
00:35:06.120 instance again notice the difference this is the class this is an instance the one in the middle self at the top
00:35:12.300 level main when you're at the top level in other words you're not inside a class definition you're not inside a method
00:35:18.990 definition you're just floating in sort of Ruby outer space Ruby creates this special object called main which really
00:35:26.610 exists its kind of the backstop object it's like it exists because there has to
00:35:31.650 be a self so it sort of bootstraps the object model by creating this this sort
00:35:38.190 of default object main and that's why
00:35:44.040 when I say you know show me itself at the top level it actually comes out as main if you type main you can't actually
00:35:50.550 refer to it as main that's just the tag or sort of rapper name that Ruby gives it but but that's the top-level object
00:36:00.240 before the top level self before you enter into any context context where self is going
00:36:06.140 to be changed this is just a quick example of instance eval I string equals
00:36:13.460 I am a string and I just I print self and then I do string dot instance eval
00:36:19.820 and here I say self is now self and put us up case basically what's happening is
00:36:26.180 again in that second line self is main right because I'm out in the top level
00:36:32.000 when you do an instance of value swap in self I've swapped in the STR the string
00:36:39.050 I've swapped that in itself for those two or three lines so everything that
00:36:44.510 happens in that instance of a block happens in relation to the self that is that I've called instance of how long
00:36:53.290 class eval similarly here I've got I've actually just created an anonymous class
00:37:00.109 myclass equals class knew if i print self in a class eval it's going to be
00:37:06.290 the class that I've called class avow on so self is important and again there's
00:37:13.369 there's all there's always one and it does it does change from one object to
00:37:21.050 another all right point number six variables contain references to objects
00:37:27.070 what that means is for example here I say string equals hi and then I say
00:37:34.160 string 2 equals string now what i've done here is i've copied a reference to
00:37:40.430 a string from one variable to another and i put it that way to make it clear that i have not copied the string i
00:37:47.450 still only have one string object and you can tell that because if i append
00:37:55.280 the word there to the second variable 3 or through the use of the second
00:38:01.340 variable and then I print out the first variable the there is there right in
00:38:07.490 other words I've manipulated the original string by using a second
00:38:12.740 variable and that's because each of those variables contains a reference to that exact object so
00:38:19.560 there's no copying going on it's it is actually the same object and that again can be a source of some confusion
00:38:27.240 especially at first when you're not sure why objects are being are being damaged
00:38:32.880 in mysterious ways this is just an example using an array essentially I create an array of three objects I copy
00:38:40.800 the reference into array two I then add an element to array two and it's sure
00:38:46.080 enough when i print array that that fourth element is present so again I'm using references to manipulate objects
00:38:53.850 but every reference refers to the same object every copy of the reference now
00:39:00.600 here's one that's kind of another slightly cautionary tale I have a
00:39:07.770 variable called one which is the string one and then I have an array that
00:39:13.080 consists of one to three notice two and three are capitalized in one isn't if I
00:39:18.180 capitalized one in place using the capitalized bang method then I've
00:39:23.970 changed the string 1 to capital oh and it that is also reflected in the array
00:39:29.670 because the array contains that same object that that object one here you see
00:39:40.530 the results or it's kind of similar behavior in the face of a method call here I have a method called add bang
00:39:47.280 which takes a string and just adds an exclamation point to it and you can see if I call add bang on a string or using
00:39:55.500 a variable using a reference it operates on exactly that object because then when
00:40:00.810 I print it out it has the ! the method does not copy the string it does not
00:40:06.090 return a copy it returned it actually operates on the original object and and
00:40:11.480 the object reflects that change note
00:40:16.620 however that if you use plus on strings or plus equals you actually get it you
00:40:22.140 do get a new string so if i say string 2 plus equals there that is not going to
00:40:27.630 affect the original string because i'm actually reassigning I'm reassigning to
00:40:35.130 the string to variable a new string that has the word there at the end so if you
00:40:40.740 if you want to not or if you want to use
00:40:45.960 copies and so forth and you can use the plus equals and that will kind of
00:40:51.300 diverge one object away from another all
00:40:56.460 right be careful with fries the thing with fries is that if you freeze an
00:41:02.010 array for example if I have an array I freeze it I try to push something onto
00:41:07.170 the array I can't do that but notice that I can change the first element in
00:41:14.970 the array right I can say array sub zero dot up case bang and here I've actually
00:41:21.180 changed the first element in the array to its up case version so be careful
00:41:26.580 with fries because and this is you know sort of it's a little bit tangential to this but it's it's sort of related to
00:41:33.170 references to you just want to be careful that even if an object is if it's a collection object and it's frozen
00:41:40.140 the items in the collection are not frozen that's what you have to be careful with all right finally just a
00:41:48.390 little bit about true and false true and false in Ruby are objects but true and
00:41:54.690 false are also states every object has a
00:42:00.150 boolean value either true or false those are the states only two objects have the
00:42:07.350 boolean value false those objects are nil and false every other object in Ruby
00:42:13.770 is true so 0 is true and empty strings are true and so forth now that's usually
00:42:21.570 if it is a source of confusion it's usually pretty brief so you know coming from other languages a lot of people
00:42:26.850 expect zero to be false for example but but it isn't and you can always run a
00:42:33.090 sort of truth test if you in anything where you can put an if and here there's
00:42:38.370 again a couple of sort of whimsical examples where I'm actually testing testing the truth of a class
00:42:43.690 definition um so if class a and put as
00:42:49.240 true well that's going to return nil so that will not be true if Class A zero and put us through that will output true
00:42:55.780 because Class A zero and evaluates to 0 which is true so this is really just to
00:43:01.600 illustrate that you can you can and this may be more of a mental exercise and something you would do with literally
00:43:07.150 with with if statements but you can always anything you want to know the truth value of you can plug into an if
00:43:12.520 statement and if it if it passes that then it's then it's true in the boolean
00:43:18.880 sense all right just a little summary of
00:43:24.030 what we've covered the seven points and again my goal in doing this is to give
00:43:29.590 you hopefully the benefit of some of my observations over the years of things
00:43:34.930 that that people have found confusing things where people have had great sort
00:43:40.030 of aha moments because they you know it's like ah classes or objects or whatever or you know Oh self changed
00:43:47.260 because I entered a method definition so hopefully like I said at the beginning hopefully some of this will you know be
00:43:55.270 helpful to you personally it may be that if you work with people or are mentoring
00:44:01.690 people who are learning ruby it'll give you a little bit of you know some ideas about trouble spots to emphasize and
00:44:08.770 make sure that they understand and I am going to stop here i have a few little
00:44:15.850 things but but we will will I think end
00:44:22.240 here because we're just about out of time are there any questions
00:44:28.250 yes suggestions for avoiding the references when you want value so if you
00:44:34.190 just do your object over the place that I guess prevents it
00:44:39.240 yeah you can you can do to avoid the reference problem yeah I mean duping is
00:44:45.630 is certainly one let you you do have to be careful also though like when remember that duping is not a deep
00:44:52.200 operation so if you do put an array you actually get a new array but it has the
00:44:57.210 same object in it so you can you have to be careful that it's a shallow dupe
00:45:03.510 operation sorry what's it for example
00:45:10.290 options are always right great so the
00:45:17.220 other suggestions for other other approaches to avoid we're doing a lot of immutable objects inheriting those right
00:45:27.540 um I mean that I think do ping is sort of it's the thing that comes to mind I
00:45:33.930 think let's say there's nothing else but that's what I think that's sort of the bread and butter technique somehow it
00:45:41.470 ends up not being too huge a problem i'm not sure why exactly but like just
00:45:46.960 people don't write that many methods that change their argument I mean I think it's sort of a bad practice anyway
00:45:52.450 to check our questionable practice to change the you know if you send an argument to a method to actually destroy
00:45:58.990 it and not you know kind of silently change it unless there's you know some really compelling reason but so I think
00:46:06.730 people just avoid some of those things that get into trouble yes more subtly or
00:46:14.200 exhausting behaviors that you have died there they actually look 25 are they discovered behaviors are they define is
00:46:22.510 it be attended movie would be like that and then that's what the extension that
00:46:27.760 is is that see rude and just Jay Ruby idiots and all the other movies compliance cute little things that
00:46:39.650 yeah I think that I mean I anyone might be able to prove me all about this i
00:46:45.630 think i've stuck two things here that are that really are in the language like
00:46:50.910 the fact that everything reduces to an object like a class definition again
00:46:56.190 there's not that many cases where you where you use that fact directly but i
00:47:01.799 believe that it is sort of inherent to the line i think in the language that everything you know that a class
00:47:08.400 definition would would evaluate to an object and if it's empty it would evaluate to know now i'm not sure
00:47:14.849 they've been talked about for example having method definitions evaluate to
00:47:20.490 symbols that are the name of the method and things like that I don't know whether any other implementation has
00:47:27.420 actually done that I don't think so but if that's something where you could
00:47:32.640 because roomie makes very little becoming basically any method definition whatever's inside it the definition
00:47:38.549 block itself evaluates to nil so that's in a way it's kind of a wasted opportunity because it could evaluate to
00:47:45.450 a name it could evaluate to a method object whatever so I'm not sure whether any any of the other
00:47:52.560 have sort of stepped into that particular space and it certainly could
00:47:57.930 happen but I think most of you know what I covered would probably I think would
00:48:02.970 apply to all
00:48:09.260 you get what okay there's yes so if you're busy as
00:48:14.410 you get back compiled method object okay what growing that the definition body all right so that's what I didn't
00:48:20.550 really talk about those but that's an example where something sort of you know in this family of things might differ
00:48:29.720 all right thank you very much
Explore all talks recorded at RubyConf 2011
+55