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