WEBVTT

1
00:00:00.120 --> 00:00:05.400
<v Speaker 1>Imagine having like a secret guy to navigate complex technical info, right,

2
00:00:05.719 --> 00:00:08.039
<v Speaker 1>something that just pulls out the coolest facts, the most

3
00:00:08.119 --> 00:00:10.800
<v Speaker 1>useful insights, and keeps you hooked the whole time.

4
00:00:10.919 --> 00:00:13.119
<v Speaker 2>That's pretty much what we're doing today, exactly.

5
00:00:13.640 --> 00:00:14.919
<v Speaker 1>This is the deep dive.

6
00:00:14.800 --> 00:00:18.359
<v Speaker 2>We're embarking on, a well a deep dive into the

7
00:00:18.359 --> 00:00:21.879
<v Speaker 2>world of Ruby programming. And our main source today is

8
00:00:22.199 --> 00:00:26.879
<v Speaker 2>The Ruby Way Solutions and Techniques in Ruby Programming, the

9
00:00:27.000 --> 00:00:31.039
<v Speaker 2>third Edition by Mark Bates. It's a fantastic resource.

10
00:00:30.679 --> 00:00:33.000
<v Speaker 1>Yeah, it really is. And our mission really is to

11
00:00:33.039 --> 00:00:36.600
<v Speaker 1>pull out those vital nuggets, those genuinely surprising facts from

12
00:00:36.679 --> 00:00:38.640
<v Speaker 1>this guide. We want to give you a shortcut, you know,

13
00:00:39.119 --> 00:00:42.320
<v Speaker 1>help you understand what makes Ruby tick, what makes it

14
00:00:42.399 --> 00:00:45.520
<v Speaker 1>so powerful and unique, without getting totally bogged down in

15
00:00:45.560 --> 00:00:46.439
<v Speaker 1>every last detail.

16
00:00:46.679 --> 00:00:48.679
<v Speaker 2>Right. And it's important to say this isn't really a

17
00:00:48.719 --> 00:00:52.600
<v Speaker 2>beginner's tutorial, No, definitely not. It's more of an outstanding reference,

18
00:00:52.759 --> 00:00:55.200
<v Speaker 2>useful whether you're just starting to explore Ruby or you've

19
00:00:55.200 --> 00:00:56.200
<v Speaker 2>been using it for years.

20
00:00:56.320 --> 00:00:58.359
<v Speaker 1>Mark Bits makes this great point in the book. He says,

21
00:00:58.399 --> 00:01:01.359
<v Speaker 1>the Ruby Way isn't just code, it's the whole philosophy

22
00:01:01.679 --> 00:01:06.079
<v Speaker 1>embraced by Ruby's creator, mats and the community exactly.

23
00:01:06.120 --> 00:01:09.680
<v Speaker 2>It's this living, evolving culture that goes way beyond just

24
00:01:09.760 --> 00:01:10.640
<v Speaker 2>syntax rules.

25
00:01:10.760 --> 00:01:14.400
<v Speaker 1>Yeah, that ineffable spirit. He talks about the roller coaster ride. Yeah,

26
00:01:14.439 --> 00:01:17.760
<v Speaker 1>it sounds really compelling. So what's one aspect of Ruby's

27
00:01:17.760 --> 00:01:21.400
<v Speaker 1>philosophy for you that really captures that feeling? Maybe something

28
00:01:21.400 --> 00:01:22.760
<v Speaker 1>that gave you inn aha moment?

29
00:01:22.840 --> 00:01:26.400
<v Speaker 2>Oh uh? For me, it's got to be the principle

30
00:01:26.400 --> 00:01:30.719
<v Speaker 2>of least surprise POLS as people often call it POLS. Okay,

31
00:01:31.159 --> 00:01:36.120
<v Speaker 2>it's this core idea that the language should just work

32
00:01:36.200 --> 00:01:40.200
<v Speaker 2>the way you expect it to. It tries to be intuitive, predictable,

33
00:01:40.319 --> 00:01:42.400
<v Speaker 2>reducing those moments where you're like, wait, why did it

34
00:01:42.480 --> 00:01:45.400
<v Speaker 2>do that? And there's even that playful counter acronym some

35
00:01:45.480 --> 00:01:51.079
<v Speaker 2>Rubists to usela lola least object oriented annoyance. It's kind

36
00:01:51.120 --> 00:01:54.400
<v Speaker 2>of a nod to preferring practical design, you know, over

37
00:01:54.480 --> 00:01:57.599
<v Speaker 2>super rigid op rules sometimes making sure stuff doesn't just

38
00:01:57.680 --> 00:01:58.239
<v Speaker 2>get in your way.

39
00:01:58.439 --> 00:02:01.400
<v Speaker 1>Least object oriented annoyance. Like that that really sets a tone,

40
00:02:01.400 --> 00:02:03.599
<v Speaker 1>doesn't it. So? Okay, when you're talking to developers, maybe

41
00:02:03.599 --> 00:02:06.159
<v Speaker 1>they're building libraries or UIs, how does this principle of

42
00:02:06.200 --> 00:02:08.439
<v Speaker 1>lease surprise actually show up in the code like a

43
00:02:08.439 --> 00:02:09.400
<v Speaker 1>concrete example.

44
00:02:09.560 --> 00:02:13.199
<v Speaker 2>Sure, well, think about method names or how common operations work.

45
00:02:13.599 --> 00:02:17.319
<v Speaker 2>If you expect a method like say chomp to actually

46
00:02:17.439 --> 00:02:18.639
<v Speaker 2>change the string it's.

47
00:02:18.439 --> 00:02:20.599
<v Speaker 1>Called on right, modify it in place.

48
00:02:20.400 --> 00:02:23.680
<v Speaker 2>Exactly it does. If you expect arithmetic operators to behave

49
00:02:23.719 --> 00:02:27.159
<v Speaker 2>normally they do. It just leads to fewer surprises, less

50
00:02:27.159 --> 00:02:30.520
<v Speaker 2>time digging through docs for basic stuff. It really builds

51
00:02:30.560 --> 00:02:33.240
<v Speaker 2>trust in the language. You feel like it's working with you.

52
00:02:33.639 --> 00:02:36.719
<v Speaker 1>That makes a lot of sense. Okay, moving into Ruby

53
00:02:36.800 --> 00:02:40.520
<v Speaker 1>syntax and semantics, it's unique flavor. I've heard the parser

54
00:02:40.639 --> 00:02:45.759
<v Speaker 1>described as complex but also relatively forgiving. What's that mean

55
00:02:45.840 --> 00:02:47.000
<v Speaker 1>for someone writing Ruby?

56
00:02:47.319 --> 00:02:50.960
<v Speaker 2>It means Ruby tries quite hard to understand what you

57
00:02:51.039 --> 00:02:53.560
<v Speaker 2>meant to write, even if it's maybe a bit ambiguous.

58
00:02:53.599 --> 00:02:55.599
<v Speaker 2>It doesn't just throw up its hands at the first

59
00:02:55.639 --> 00:02:58.360
<v Speaker 2>sign of trouble like some stricter parsers might write.

60
00:02:58.400 --> 00:03:00.400
<v Speaker 1>It gives you a bit of leeway exactly.

61
00:03:00.080 --> 00:03:03.400
<v Speaker 2>Which can be really convenient. Let's express things more naturally sometimes.

62
00:03:03.560 --> 00:03:06.639
<v Speaker 1>Okay, now here's a classic Ruby quirk, something that often

63
00:03:06.680 --> 00:03:10.080
<v Speaker 1>trips people up coming from other languages. Truthiness. Can you

64
00:03:10.240 --> 00:03:10.919
<v Speaker 1>walk us through that?

65
00:03:11.240 --> 00:03:13.719
<v Speaker 2>Yeah, This is a big one. In Ruby, only two

66
00:03:13.840 --> 00:03:17.560
<v Speaker 2>things are considered false in a boolean context, the special

67
00:03:17.639 --> 00:03:20.520
<v Speaker 2>value nil and the boolean false itself.

68
00:03:21.080 --> 00:03:22.360
<v Speaker 1>Those two, Just those two.

69
00:03:22.520 --> 00:03:25.719
<v Speaker 2>Everything else, and I mean everything, an empty string, the

70
00:03:25.800 --> 00:03:28.520
<v Speaker 2>numbers are away, an empty array, empty hash. All of

71
00:03:28.560 --> 00:03:30.000
<v Speaker 2>it evaluates to true.

72
00:03:30.080 --> 00:03:34.039
<v Speaker 1>Wow. Okay, so zero isn't false like in C or JavaScript.

73
00:03:34.199 --> 00:03:37.280
<v Speaker 2>Nope. That's a common gotcha definitely, But once you get

74
00:03:37.360 --> 00:03:40.000
<v Speaker 2>used to it, it actually simplifies a lot of conditional logic.

75
00:03:40.120 --> 00:03:43.159
<v Speaker 2>You don't need explicit checks for nil or false all

76
00:03:43.199 --> 00:03:43.520
<v Speaker 2>the time.

77
00:03:43.680 --> 00:03:46.759
<v Speaker 1>Good to know. What about that convention of methods ending

78
00:03:46.759 --> 00:03:49.400
<v Speaker 1>with an exclamation point like chomp?

79
00:03:49.639 --> 00:03:51.759
<v Speaker 2>The book calls them dangerous.

80
00:03:51.240 --> 00:03:54.080
<v Speaker 1>Right, the bang methods The thing is a strong visual cue.

81
00:03:54.199 --> 00:03:56.919
<v Speaker 1>It's a warning sign basically warning Yeah. It signals that

82
00:03:56.960 --> 00:04:00.560
<v Speaker 1>the method modifies the object it's called on directly in place,

83
00:04:00.879 --> 00:04:04.039
<v Speaker 1>instead of returning a new modified version. It has a

84
00:04:04.080 --> 00:04:06.879
<v Speaker 1>side effect, as they say, so, string dot chomp gives

85
00:04:06.879 --> 00:04:09.080
<v Speaker 1>you a new string without the new line. But string

86
00:04:09.120 --> 00:04:11.080
<v Speaker 1>dot chomp changes the original string.

87
00:04:11.240 --> 00:04:14.360
<v Speaker 2>Ah. Okay, so the bang means watch out, this changes

88
00:04:14.400 --> 00:04:20.079
<v Speaker 2>the original precisely. It's all about clarity and avoiding nasty surprises.

89
00:04:20.439 --> 00:04:23.560
<v Speaker 1>And speaking of clarity, even similar looking operators can behave

90
00:04:23.560 --> 00:04:25.519
<v Speaker 1>differently right like versus.

91
00:04:25.279 --> 00:04:27.759
<v Speaker 2>The word or yeah, that's a subtle but important one.

92
00:04:27.800 --> 00:04:31.000
<v Speaker 2>They both do logical oar but has higher precedence. Higher

93
00:04:31.040 --> 00:04:34.560
<v Speaker 2>precedence meaning it binds more tightly in expressions you almost

94
00:04:34.800 --> 00:04:38.199
<v Speaker 2>always want to use because using or can lead to

95
00:04:38.319 --> 00:04:41.079
<v Speaker 2>unexpected results if you're not careful with parentheses. It's just

96
00:04:41.399 --> 00:04:42.720
<v Speaker 2>clearer and safer.

97
00:04:43.120 --> 00:04:46.439
<v Speaker 1>Got it, use the pipes. Now, the case statement in Ruby,

98
00:04:46.800 --> 00:04:48.399
<v Speaker 1>it's more than just a simple switch, isn't it?

99
00:04:48.439 --> 00:04:51.120
<v Speaker 2>Oh? Absolutely, it's way more powerful. It doesn't use simple

100
00:04:51.240 --> 00:04:55.879
<v Speaker 2>quality checking. It uses this special operator three equal signs.

101
00:04:55.759 --> 00:04:57.160
<v Speaker 1>Triple equals. Okay, what does that do?

102
00:04:57.439 --> 00:05:00.160
<v Speaker 2>Think of it? Less as is exactly equal to? And

103
00:05:00.199 --> 00:05:02.560
<v Speaker 2>more like? Is a kind of or does it match

104
00:05:02.600 --> 00:05:06.040
<v Speaker 2>this pattern? It's called case equality or relationship operator?

105
00:05:06.120 --> 00:05:07.240
<v Speaker 1>So what can you match against?

106
00:05:07.480 --> 00:05:10.040
<v Speaker 2>All sorts of things? You can check if an object

107
00:05:10.079 --> 00:05:12.600
<v Speaker 2>is an instance of a certain class, if a number

108
00:05:12.639 --> 00:05:15.720
<v Speaker 2>falls within a range, if a string matches a rejects.

109
00:05:16.160 --> 00:05:19.759
<v Speaker 2>It makes case statements incredibly versatile for handling different types

110
00:05:19.800 --> 00:05:22.040
<v Speaker 2>of input or situations very elegantly.

111
00:05:22.519 --> 00:05:25.920
<v Speaker 1>That sounds really powerful. Now here's something the book highlights

112
00:05:25.959 --> 00:05:30.360
<v Speaker 1>as one of Ruby's superpowers. Definitions in Ruby are executed.

113
00:05:30.720 --> 00:05:32.160
<v Speaker 1>What exactly does that unlock?

114
00:05:32.399 --> 00:05:36.680
<v Speaker 2>This is? This is fundamental to Ruby's dynamism. It means

115
00:05:36.720 --> 00:05:39.240
<v Speaker 2>that defining a method, or a class or even a

116
00:05:39.240 --> 00:05:42.759
<v Speaker 2>block of code isn't just a static declaration the compiler

117
00:05:42.800 --> 00:05:46.519
<v Speaker 2>handles once it's code that runs at runtime.

118
00:05:46.279 --> 00:05:49.600
<v Speaker 1>Code that runs. So you can define things conditionally exactly.

119
00:05:49.680 --> 00:05:51.879
<v Speaker 2>You could have an if statement and based on some

120
00:05:51.920 --> 00:05:54.560
<v Speaker 2>condition at runtime, you could define method a one way

121
00:05:54.879 --> 00:05:57.399
<v Speaker 2>or define it completely differently. You can literally build or

122
00:05:57.439 --> 00:05:59.759
<v Speaker 2>modify parts of your program while it's running.

123
00:06:00.000 --> 00:06:03.279
<v Speaker 1>Oh, so the program can kind of reshape.

124
00:06:02.839 --> 00:06:06.399
<v Speaker 2>Itself in a way. Yes, it allows for incredible flexibility

125
00:06:06.399 --> 00:06:10.439
<v Speaker 2>and metaprogramming, building domain specific languages. It's a deep topic,

126
00:06:10.480 --> 00:06:13.240
<v Speaker 2>but that dynamic execution of definitions is key.

127
00:06:13.360 --> 00:06:15.800
<v Speaker 1>That sounds like a game changer for certain kinds of problems.

128
00:06:16.079 --> 00:06:19.040
<v Speaker 2>It really can be. And beyond that, Ruby is a

129
00:06:19.040 --> 00:06:23.160
<v Speaker 2>few other maybe smaller but still characteristic quirks, like and

130
00:06:23.279 --> 00:06:25.800
<v Speaker 2>if statements you use elsif not else.

131
00:06:25.600 --> 00:06:28.199
<v Speaker 1>If elsif one word, got it.

132
00:06:28.120 --> 00:06:31.199
<v Speaker 2>And some common words you might think are keywords aren't

133
00:06:31.240 --> 00:06:32.360
<v Speaker 2>strictly reserved.

134
00:06:33.000 --> 00:06:35.319
<v Speaker 1>Loop For example, loop isn't a keywords.

135
00:06:35.439 --> 00:06:38.439
<v Speaker 2>Nope, it's actually a method provided by the kernel module,

136
00:06:38.680 --> 00:06:42.399
<v Speaker 2>which gets mixed into objects, so it's available everywhere. It

137
00:06:42.439 --> 00:06:45.639
<v Speaker 2>speaks to Ruby's flexible grammar. But yeah, it's a method call.

138
00:06:45.639 --> 00:06:48.000
<v Speaker 1>Interesting and variable prefixes.

139
00:06:47.560 --> 00:06:50.720
<v Speaker 2>Right at signals a class variable. Yeah, that belongs to

140
00:06:50.759 --> 00:06:53.240
<v Speaker 2>the class itself, shared by all instances. So if you

141
00:06:53.279 --> 00:06:56.480
<v Speaker 2>had a my dog's class at owner name would be

142
00:06:56.480 --> 00:06:59.040
<v Speaker 2>the same for all dog objects created from that class.

143
00:06:59.079 --> 00:07:01.199
<v Speaker 1>Okay, shared across an instances. Yeah.

144
00:07:01.439 --> 00:07:04.839
<v Speaker 2>And another counterintuitive one can be unless sels the aul's

145
00:07:04.879 --> 00:07:07.639
<v Speaker 2>part runs if the unless condition is actually true, it

146
00:07:07.720 --> 00:07:10.040
<v Speaker 2>reads a bit backwards sometimes, Uh.

147
00:07:09.680 --> 00:07:10.879
<v Speaker 1>Okay, gotta watch out for that.

148
00:07:11.199 --> 00:07:15.240
<v Speaker 2>And simple types things like integers, fixing them traditionally now

149
00:07:15.319 --> 00:07:18.600
<v Speaker 2>just integer true, false, nil. They're passed around as immediate values.

150
00:07:18.639 --> 00:07:22.439
<v Speaker 2>You can't, like modify the number five from inside a method.

151
00:07:22.399 --> 00:07:26.519
<v Speaker 1>Makes sense, And methods implicitly return values always.

152
00:07:26.800 --> 00:07:29.360
<v Speaker 2>A method returns the result of the very last expression

153
00:07:29.360 --> 00:07:31.959
<v Speaker 2>evaluated in its body, so you often don't need to

154
00:07:32.040 --> 00:07:34.680
<v Speaker 2>write return explicitly, which can make code cleaner.

155
00:07:35.040 --> 00:07:39.160
<v Speaker 1>And that if zero dollar equalspily thing you see sometimes.

156
00:07:38.759 --> 00:07:42.160
<v Speaker 2>Ah, yeah, that's a common idiom. Zero dollars is the

157
00:07:42.199 --> 00:07:44.120
<v Speaker 2>name of the script being run and file E is

158
00:07:44.160 --> 00:07:46.360
<v Speaker 2>the name of the current file, So that check is

159
00:07:46.399 --> 00:07:49.319
<v Speaker 2>basically asking am I being run directly as a script,

160
00:07:49.480 --> 00:07:51.560
<v Speaker 2>and if it is, then the code inside that if

161
00:07:51.560 --> 00:07:54.279
<v Speaker 2>block runs. It's often used to put example usage code

162
00:07:54.360 --> 00:07:57.480
<v Speaker 2>or simple tests right inside the library file itself, but

163
00:07:57.560 --> 00:08:00.160
<v Speaker 2>have it only run when you execute that file directly,

164
00:08:00.360 --> 00:08:03.199
<v Speaker 2>not when it's required as a library by another program.

165
00:08:03.319 --> 00:08:05.920
<v Speaker 1>Clever. So lots of these little design choices add up

166
00:08:05.959 --> 00:08:08.480
<v Speaker 1>to make Ruby feel well.

167
00:08:08.319 --> 00:08:12.560
<v Speaker 2>Ruby esque, exactly, flexible, often intuitive, but definitely requires you

168
00:08:12.639 --> 00:08:14.720
<v Speaker 2>to embrace the Ruby way to get the most out

169
00:08:14.720 --> 00:08:14.959
<v Speaker 2>of it.

170
00:08:15.079 --> 00:08:18.759
<v Speaker 1>Okay, we've touched on the philosophy syntax quirks, but Ruby's

171
00:08:18.759 --> 00:08:21.240
<v Speaker 1>elegance really comes into focus when we talk about object

172
00:08:21.319 --> 00:08:24.279
<v Speaker 1>oriented programming, doesn't it. It's not just tacked on. It

173
00:08:24.360 --> 00:08:25.480
<v Speaker 1>seems deeply.

174
00:08:25.319 --> 00:08:29.600
<v Speaker 2>Ingrained, absolutely, and you know, historically OOP had so much

175
00:08:29.680 --> 00:08:32.159
<v Speaker 2>hype around it. There's that great quote from Roger King.

176
00:08:32.399 --> 00:08:34.000
<v Speaker 2>Oh yeah, if you want to sell a cat to

177
00:08:34.039 --> 00:08:36.720
<v Speaker 2>a computer scientist, you have to tell him it's object oriented.

178
00:08:36.759 --> 00:08:37.639
<v Speaker 2>It was the buzzword.

179
00:08:38.000 --> 00:08:42.399
<v Speaker 1>Huh, that's brilliant. But in Ruby it feels less like

180
00:08:42.519 --> 00:08:45.879
<v Speaker 1>hype and more like a genuinely useful tool right, a

181
00:08:45.919 --> 00:08:47.720
<v Speaker 1>meaningful way to think about problems.

182
00:08:47.720 --> 00:08:50.360
<v Speaker 2>As the book says exactly, it's not a magic bullet,

183
00:08:50.360 --> 00:08:54.000
<v Speaker 2>but a powerful approach. And Ruby fully embraces the core

184
00:08:54.159 --> 00:08:59.960
<v Speaker 2>op concepts, objects with encapsulation methods showing polymorphism, classes with

185
00:09:00.039 --> 00:09:02.320
<v Speaker 2>than Herodin's hierarchies. It's all there.

186
00:09:02.519 --> 00:09:05.399
<v Speaker 1>So when you create an object and stantiate it. Ruby

187
00:09:05.399 --> 00:09:07.120
<v Speaker 1>has a constructor concept.

188
00:09:06.840 --> 00:09:10.360
<v Speaker 2>Yes, the initialized method. If you define an initialized method

189
00:09:10.399 --> 00:09:13.080
<v Speaker 2>in your class, it gets called automatically whenever a new

190
00:09:13.120 --> 00:09:15.799
<v Speaker 2>object of that class is created using dot new.

191
00:09:15.840 --> 00:09:19.000
<v Speaker 1>Okay standard constructor. What about destructors cleaning things up?

192
00:09:19.200 --> 00:09:23.440
<v Speaker 2>That's interesting because Ruby has a really effective, well behaved

193
00:09:23.480 --> 00:09:27.480
<v Speaker 2>garbage collection mechanism. It generally does not have any concept

194
00:09:27.480 --> 00:09:31.080
<v Speaker 2>of a destructor. You don't typically need to manually manage

195
00:09:31.159 --> 00:09:35.000
<v Speaker 2>memory deallocation like in some other languages. The garbage collector

196
00:09:35.000 --> 00:09:38.399
<v Speaker 2>handles finding and cleaning up objects that are no longer reachable.

197
00:09:38.600 --> 00:09:42.360
<v Speaker 1>Nice okay. Attributes instance versus class attribute right.

198
00:09:42.399 --> 00:09:46.120
<v Speaker 2>Instance attributes usually written with a single at age, belong

199
00:09:46.240 --> 00:09:49.440
<v Speaker 2>to a specific object instance. Each dog object would have

200
00:09:49.480 --> 00:09:50.200
<v Speaker 2>its own at.

201
00:09:50.080 --> 00:09:52.120
<v Speaker 1>Age unique to each object. Yes.

202
00:09:52.399 --> 00:09:56.919
<v Speaker 2>Class attributes written at owner name belong to the class itself.

203
00:09:56.919 --> 00:09:59.759
<v Speaker 2>They're shared across all instances of that class. So all

204
00:09:59.840 --> 00:10:02.000
<v Speaker 2>my dog's objects would share the same at.

205
00:10:01.960 --> 00:10:04.279
<v Speaker 1>Owner name shared value is that common.

206
00:10:04.360 --> 00:10:07.519
<v Speaker 2>It exists, But you have to be careful at variables

207
00:10:07.519 --> 00:10:10.240
<v Speaker 2>because they're also inherited by subclasses in ways that can

208
00:10:10.279 --> 00:10:14.279
<v Speaker 2>sometimes be surprising. Often, a better alternative for storing data

209
00:10:14.320 --> 00:10:16.840
<v Speaker 2>related only to the class itself and not shared with

210
00:10:16.879 --> 00:10:19.720
<v Speaker 2>instances or subclasses in the same way is to use

211
00:10:19.759 --> 00:10:22.240
<v Speaker 2>an instance variable inside a class method.

212
00:10:22.559 --> 00:10:26.279
<v Speaker 1>An instance variable inside a class method yeah, okay, a

213
00:10:26.320 --> 00:10:27.000
<v Speaker 1>bit more nuanced.

214
00:10:27.120 --> 00:10:29.919
<v Speaker 2>Yeah, it's called a class instance variable. It avoids some

215
00:10:29.960 --> 00:10:32.519
<v Speaker 2>of the pitfalls at variable.

216
00:10:32.200 --> 00:10:36.600
<v Speaker 1>Good distinction, and methods instance versus class pretty straightforward.

217
00:10:36.759 --> 00:10:39.960
<v Speaker 2>Instance methods operate on the data of a specific object

218
00:10:40.200 --> 00:10:44.080
<v Speaker 2>at age, et cetera. Class methods often define like def

219
00:10:44.159 --> 00:10:47.639
<v Speaker 2>self dot sum method performed tasks related to the class

220
00:10:47.639 --> 00:10:50.960
<v Speaker 2>as a whole, maybe like creating instances with specific properties

221
00:10:51.039 --> 00:10:54.279
<v Speaker 2>or managing class level state. They achieve class wide effects,

222
00:10:54.399 --> 00:10:55.200
<v Speaker 2>and Ruby.

223
00:10:54.919 --> 00:10:57.480
<v Speaker 1>Has those handy shortcuts for getters and setters.

224
00:10:57.559 --> 00:11:00.120
<v Speaker 2>Oh yeah, at reader at writer and a traccessor there

225
00:11:00.200 --> 00:11:03.840
<v Speaker 2>super common at reader dot name automatically creates a method

226
00:11:03.879 --> 00:11:07.159
<v Speaker 2>name to read the at name instance variable at writer

227
00:11:07.320 --> 00:11:09.559
<v Speaker 2>creates name to write it, and at t accessor does both.

228
00:11:09.639 --> 00:11:11.600
<v Speaker 1>Gives a lot of boilerplate code totally.

229
00:11:11.279 --> 00:11:14.559
<v Speaker 2>And inside an instance method, the keyword self always refers

230
00:11:14.559 --> 00:11:17.120
<v Speaker 2>to the object the method was called on the receiver wellout.

231
00:11:17.120 --> 00:11:19.759
<v Speaker 1>Controlling access public private.

232
00:11:19.480 --> 00:11:23.879
<v Speaker 2>Ruby uses public, private, and protected keywords to control method visibility.

233
00:11:24.519 --> 00:11:28.200
<v Speaker 2>By default, methods are public. Private methods can only be

234
00:11:28.240 --> 00:11:32.840
<v Speaker 2>called implicitly without an explicit receiver like self from within

235
00:11:32.960 --> 00:11:37.080
<v Speaker 2>the defining class. Protected is similar to private, but allows

236
00:11:37.120 --> 00:11:40.879
<v Speaker 2>calls from other instances of the same class or subclasses.

237
00:11:40.360 --> 00:11:42.159
<v Speaker 1>And the instance variables themselves.

238
00:11:42.240 --> 00:11:46.000
<v Speaker 2>The at ones critically instance variables at my var are

239
00:11:46.080 --> 00:11:48.600
<v Speaker 2>always private. You can only access them from outside the

240
00:11:48.639 --> 00:11:52.840
<v Speaker 2>object if the class explicitly provides accessor methods like those

241
00:11:52.879 --> 00:11:53.600
<v Speaker 2>generated by a.

242
00:11:53.519 --> 00:11:55.600
<v Speaker 1>Treater always private and class methods.

243
00:11:55.679 --> 00:11:58.320
<v Speaker 2>You can control their visibility too, using private class method

244
00:11:58.360 --> 00:12:00.399
<v Speaker 2>dot my class method right now.

245
00:12:00.480 --> 00:12:04.519
<v Speaker 1>Inheritance the book calls code reuse the holy grail of

246
00:12:04.519 --> 00:12:08.279
<v Speaker 1>computer science. How does inheritance fit into Ruby's OOP.

247
00:12:08.399 --> 00:12:11.159
<v Speaker 2>It's a core strength. Inheritance lets you create a new

248
00:12:11.200 --> 00:12:14.879
<v Speaker 2>class a subclass that inherits properties and methods from an

249
00:12:14.919 --> 00:12:18.080
<v Speaker 2>existing class. A superclass. You can then add new features

250
00:12:18.159 --> 00:12:21.320
<v Speaker 2>or override existing ones in the subclass. It's a fundamental

251
00:12:21.320 --> 00:12:23.240
<v Speaker 2>way to reuse code and model is.

252
00:12:23.279 --> 00:12:25.480
<v Speaker 1>Relationships build on what's already there.

253
00:12:25.600 --> 00:12:31.600
<v Speaker 2>Exactly, and that leads directly to polymorphism, which means literally

254
00:12:31.720 --> 00:12:35.720
<v Speaker 2>many forms. It's the idea that different objects can respond

255
00:12:35.759 --> 00:12:38.840
<v Speaker 2>to the same message, the same method call in different ways.

256
00:12:39.480 --> 00:12:44.240
<v Speaker 2>Often people mean inheritance polymorphism, where a subclass can redefine

257
00:12:44.240 --> 00:12:47.799
<v Speaker 2>a method inherited from its superclass, providing a specialized version

258
00:12:47.840 --> 00:12:50.360
<v Speaker 2>of that behavior. So you can treat objects of different

259
00:12:50.480 --> 00:12:54.960
<v Speaker 2>subclasses similarly, but they'll act appropriately based on their specific type.

260
00:12:55.159 --> 00:12:57.519
<v Speaker 1>Okay, so you can call dot speak on different animal

261
00:12:57.559 --> 00:13:00.559
<v Speaker 1>objects and they each make their own sound perfect. Example.

262
00:13:00.759 --> 00:13:03.440
<v Speaker 2>Now where Ruby gets really cool for understanding your code

263
00:13:03.519 --> 00:13:04.360
<v Speaker 2>is its reflection.

264
00:13:04.519 --> 00:13:07.279
<v Speaker 1>API reflection like looking in a mirror.

265
00:13:07.039 --> 00:13:09.720
<v Speaker 2>Kind of it lets your program examine itself at runtime.

266
00:13:09.799 --> 00:13:13.360
<v Speaker 2>You can ask objects about their type, their capabilities, their ancestry.

267
00:13:12.960 --> 00:13:13.960
<v Speaker 1>What methods do you use.

268
00:13:14.080 --> 00:13:16.360
<v Speaker 2>You can use dot class to get the exact class

269
00:13:16.360 --> 00:13:19.679
<v Speaker 2>of an object. Then there's ISA or it's alias kind

270
00:13:19.759 --> 00:13:22.440
<v Speaker 2>of these check if an object is an instance of

271
00:13:22.480 --> 00:13:24.919
<v Speaker 2>a specific class or any of its superclasses.

272
00:13:25.000 --> 00:13:26.639
<v Speaker 1>Ah, the dog is a mammal thing.

273
00:13:26.720 --> 00:13:30.440
<v Speaker 2>Exactly mydog dot ISA mammal would be true, but instance

274
00:13:30.480 --> 00:13:34.279
<v Speaker 2>of stricter mydog dot instance mammal would be false because

275
00:13:34.279 --> 00:13:37.519
<v Speaker 2>its direct class is dog dot. ISA also works with

276
00:13:37.600 --> 00:13:39.840
<v Speaker 2>modules that have been mixed in, which is super useful.

277
00:13:40.159 --> 00:13:43.559
<v Speaker 2>An array ISA innumerable for instance.

278
00:13:43.240 --> 00:13:47.200
<v Speaker 1>So ISA checks the whole inheritance chain and mix its right.

279
00:13:47.440 --> 00:13:50.440
<v Speaker 2>And sometimes maybe the most important check is respond to

280
00:13:50.440 --> 00:13:53.399
<v Speaker 2>respond to yeah, it just asks, hey, object, can you

281
00:13:53.440 --> 00:13:55.879
<v Speaker 2>do this thing? It checks if the object has a

282
00:13:55.879 --> 00:13:58.919
<v Speaker 2>method with a given name, regardless of its class or inheritance.

283
00:13:59.360 --> 00:14:02.080
<v Speaker 2>This is key to Ruby's duck typing. If it walks

284
00:14:02.120 --> 00:14:03.879
<v Speaker 2>like a duck and quacks like a duck, just treat

285
00:14:03.879 --> 00:14:06.120
<v Speaker 2>it like a duck. If it responds to it dot quack,

286
00:14:06.200 --> 00:14:07.600
<v Speaker 2>you can call dot quack on it.

287
00:14:07.679 --> 00:14:10.320
<v Speaker 1>Focus on capabilities, not just lineage precisely.

288
00:14:10.519 --> 00:14:13.480
<v Speaker 2>You can also use methods like constants to see defined constants,

289
00:14:13.600 --> 00:14:16.840
<v Speaker 2>nesting to see the current module class nesting, and ancestors

290
00:14:16.879 --> 00:14:20.200
<v Speaker 2>to get the full inheritance chain, including mixin's for a class.

291
00:14:20.559 --> 00:14:25.279
<v Speaker 2>It's incredibly powerful for understanding and even manipulating your program dynamically.

292
00:14:25.519 --> 00:14:29.399
<v Speaker 1>Okay, that dynamic introspection sounds really powerful. Let's shift gears

293
00:14:29.399 --> 00:14:33.159
<v Speaker 1>slightly and dive into practical mastery, starting with strings. The

294
00:14:33.159 --> 00:14:35.799
<v Speaker 1>book poses that question from a computer science professor.

295
00:14:35.919 --> 00:14:38.879
<v Speaker 2>Ah, yes, what is the most important data type?

296
00:14:39.360 --> 00:14:41.960
<v Speaker 1>And the answer was this string.

297
00:14:42.120 --> 00:14:45.399
<v Speaker 2>Which when you think about it, web pages, source code,

298
00:14:45.639 --> 00:14:49.799
<v Speaker 2>user input documents, configuration files, so much of what computers

299
00:14:49.799 --> 00:14:50.799
<v Speaker 2>handle is text.

300
00:14:51.200 --> 00:14:54.000
<v Speaker 1>It makes sense and Ruby's strings are pretty flexible, right.

301
00:14:53.919 --> 00:14:57.759
<v Speaker 2>Very flexible. You have your standard single and double quoted strings.

302
00:14:58.159 --> 00:15:03.440
<v Speaker 2>Double quoted strings allow interpal and escape sequences like n interpolation. Yeah,

303
00:15:03.519 --> 00:15:06.759
<v Speaker 2>Embedding Ruby code inside a string using hashtag pv e

304
00:15:07.039 --> 00:15:10.639
<v Speaker 2>us so hello hashtag your name would put the value

305
00:15:10.639 --> 00:15:13.840
<v Speaker 2>of the name variable right into the string. It implicitly

306
00:15:13.879 --> 00:15:16.120
<v Speaker 2>calls narrows on whatever's inside the braces.

307
00:15:16.200 --> 00:15:18.279
<v Speaker 1>Andy, what about other ways to make strings?

308
00:15:18.399 --> 00:15:21.440
<v Speaker 2>There are alternate quoting mechanisms like per set tea for

309
00:15:21.480 --> 00:15:23.840
<v Speaker 2>single quoted behavior and percent highs two two one r

310
00:15:23.919 --> 00:15:27.039
<v Speaker 2>tq for double quoted behavior. Useful if your string contains

311
00:15:27.080 --> 00:15:30.080
<v Speaker 2>lots of quotes itself. And then there are here documents

312
00:15:30.159 --> 00:15:33.840
<v Speaker 2>using identifier identifier which are great for embedding large multi

313
00:15:33.879 --> 00:15:34.840
<v Speaker 2>line blocks of text.

314
00:15:35.120 --> 00:15:38.039
<v Speaker 1>Okay, lots of ways to represent them YEA, manipulating them.

315
00:15:37.960 --> 00:15:41.240
<v Speaker 2>Tons of power. There you can get the length, process

316
00:15:41.279 --> 00:15:43.639
<v Speaker 2>them line by line using each line, or character by

317
00:15:43.679 --> 00:15:47.320
<v Speaker 2>character with each char. You can extract substrings using ranges

318
00:15:47.360 --> 00:15:50.320
<v Speaker 2>like mystering eight point one three, or even using regular

319
00:15:50.360 --> 00:15:52.279
<v Speaker 2>expressions like mistring pattern.

320
00:15:52.080 --> 00:15:55.120
<v Speaker 1>Using rejects for extraction. Nice white space.

321
00:15:54.879 --> 00:15:57.919
<v Speaker 2>Easy strip removes leading and trailing white space, L strip

322
00:15:58.080 --> 00:16:01.559
<v Speaker 2>just leading, l strip just trailing. Very common operations, and

323
00:16:01.639 --> 00:16:04.879
<v Speaker 2>you can repeat strings with the multiplication operator not ten

324
00:16:04.960 --> 00:16:05.759
<v Speaker 2>plus batman.

325
00:16:06.120 --> 00:16:11.279
<v Speaker 1>Huh. Okay, now that interpolation with hashtagzines common. Are there pitfalls?

326
00:16:11.480 --> 00:16:14.399
<v Speaker 2>The main pitfall mentioned, and it's a big one, is

327
00:16:14.559 --> 00:16:17.919
<v Speaker 2>using Evil for anything involving external input. Evil takes a

328
00:16:17.960 --> 00:16:20.000
<v Speaker 2>string and executes it as ruby code.

329
00:16:20.120 --> 00:16:22.600
<v Speaker 1>Sounds powerful and dangerous.

330
00:16:22.200 --> 00:16:25.320
<v Speaker 2>Extremely dangerous if the string comes from an untrusted source

331
00:16:25.440 --> 00:16:28.159
<v Speaker 2>like user input. The book flat out calls it almost

332
00:16:28.200 --> 00:16:31.039
<v Speaker 2>always the worst option. It's slow and opens up massive

333
00:16:31.080 --> 00:16:34.639
<v Speaker 2>security holes. You should basically never use Evil on external data.

334
00:16:34.720 --> 00:16:37.919
<v Speaker 2>It's really only for very specific metaprogramming task where you

335
00:16:37.960 --> 00:16:40.120
<v Speaker 2>fully control the code being evaluated.

336
00:16:40.360 --> 00:16:43.960
<v Speaker 1>Okay, big red flag on Evil. Good to know any

337
00:16:44.000 --> 00:16:45.480
<v Speaker 1>other cool string utilities.

338
00:16:45.759 --> 00:16:49.320
<v Speaker 2>The book mentions things like calculating Levenstein distance the edit

339
00:16:49.360 --> 00:16:53.480
<v Speaker 2>distance between two strings, useful for spell checkers or finding similarities.

340
00:16:53.840 --> 00:16:57.240
<v Speaker 2>And it points to libraries like active support from rails

341
00:16:57.480 --> 00:16:59.840
<v Speaker 2>which add helpful methods like word wrap.

342
00:17:00.080 --> 00:17:03.399
<v Speaker 1>Right, let's move from text to numbers. The computer's native tongue.

343
00:17:03.399 --> 00:17:06.920
<v Speaker 1>As you said, Ruby handles the basics integers floats. But

344
00:17:07.039 --> 00:17:08.720
<v Speaker 1>what are the pleasant surprises.

345
00:17:09.160 --> 00:17:13.279
<v Speaker 2>Oh, Ruby's numerical tower is quite sophisticated beyond standard integers.

346
00:17:13.319 --> 00:17:16.039
<v Speaker 2>If a number gets too big, it automatically transitions into

347
00:17:16.079 --> 00:17:20.640
<v Speaker 2>a big num, allowing for arbitrarily large integer calculations without overflow.

348
00:17:20.720 --> 00:17:22.759
<v Speaker 1>Automatic handling of huge numbers. Nice.

349
00:17:22.839 --> 00:17:26.279
<v Speaker 2>Then there's Big Decimal standard Floating point numbers float can

350
00:17:26.319 --> 00:17:29.480
<v Speaker 2>have tiny precision errors because of how they're represented in binary.

351
00:17:29.759 --> 00:17:31.680
<v Speaker 2>You know, zero point one plus point two not being

352
00:17:31.720 --> 00:17:35.480
<v Speaker 2>exactly point three. Big decimal solves this by providing precise

353
00:17:35.640 --> 00:17:38.279
<v Speaker 2>decimal arithmetic, crucial for financial.

354
00:17:37.759 --> 00:17:40.839
<v Speaker 1>Calculations, so for money, use Big decimal definitely.

355
00:17:40.960 --> 00:17:44.400
<v Speaker 2>And there's also rational for representing exact fractions like rational

356
00:17:44.440 --> 00:17:49.119
<v Speaker 2>one three. This avoids floating point inaccuracies entirely for division

357
00:17:49.119 --> 00:17:55.720
<v Speaker 2>that results in repeating decimals, for instance, rational one hundred zero, zero, one, one, rational, three,

358
00:17:55.759 --> 00:17:57.559
<v Speaker 2>one thousand keeps perfect precision.

359
00:17:57.759 --> 00:18:02.160
<v Speaker 1>Wow. Okay, so bigm big decimal, rational, pretty comprehensive. What

360
00:18:02.240 --> 00:18:03.359
<v Speaker 1>about complex numbers?

361
00:18:03.640 --> 00:18:06.480
<v Speaker 2>Yep, built right in you can create complex numbers easily.

362
00:18:06.799 --> 00:18:09.519
<v Speaker 2>Three dot im gives you the imaginary number three I,

363
00:18:09.720 --> 00:18:13.720
<v Speaker 2>and you can perform standard complex arithmetic. There's also complex

364
00:18:13.759 --> 00:18:17.200
<v Speaker 2>dot polar for polar coordinates. It shows Ruby's strength beyond

365
00:18:17.319 --> 00:18:19.799
<v Speaker 2>just web deev. It's capable in scientific context too.

366
00:18:19.880 --> 00:18:22.119
<v Speaker 1>Cool. Any advanced math stuff, Yeah.

367
00:18:22.119 --> 00:18:24.920
<v Speaker 2>Ruby has built in support for prime number operations. Through

368
00:18:24.960 --> 00:18:27.960
<v Speaker 2>the prime library. You can test for primality, generate primes,

369
00:18:27.960 --> 00:18:30.920
<v Speaker 2>and even get the prime factorization of a number using prime.

370
00:18:30.759 --> 00:18:33.160
<v Speaker 1>Division prime division. Okay, statistics yep.

371
00:18:33.200 --> 00:18:36.240
<v Speaker 2>There are common statistical functions available, often through gems or

372
00:18:36.279 --> 00:18:39.680
<v Speaker 2>standard library editions, for calculating things like mean, median mode,

373
00:18:39.759 --> 00:18:44.119
<v Speaker 2>standard deviation, variance, correlation coefficients, the usual suspects for basic

374
00:18:44.160 --> 00:18:45.079
<v Speaker 2>data analysis.

375
00:18:45.319 --> 00:18:48.119
<v Speaker 1>One last thing on numbers. That quote about random numbers, ah,

376
00:18:48.240 --> 00:18:49.039
<v Speaker 1>John von Neuman.

377
00:18:49.200 --> 00:18:54.000
<v Speaker 2>Yes, Ruby's rand function, like in most languages, generate pseudorandom numbers.

378
00:18:54.240 --> 00:18:58.039
<v Speaker 2>They look random, but they're produced by a deterministic algorithm.

379
00:18:58.039 --> 00:18:59.519
<v Speaker 1>So not truly random.

380
00:18:59.799 --> 00:19:04.079
<v Speaker 2>Now truly unpredictable in a physical sense. Von Neumann's quote

381
00:19:04.279 --> 00:19:08.440
<v Speaker 2>anyone who attempts to generate random numbers by deterministic means is,

382
00:19:08.799 --> 00:19:11.160
<v Speaker 2>of course living in a state of sin is just

383
00:19:11.200 --> 00:19:15.000
<v Speaker 2>a witty reminder of that limitation. It's important to understand

384
00:19:15.039 --> 00:19:17.519
<v Speaker 2>what computer randomness actually is.

385
00:19:17.759 --> 00:19:20.519
<v Speaker 1>A great point. Okay, let's shift to organizing data and

386
00:19:20.640 --> 00:19:25.079
<v Speaker 1>time collections like arrays and hashes and how Ruby handles time.

387
00:19:25.400 --> 00:19:28.559
<v Speaker 1>These seem like areas where Ruby really offers elegant solutions.

388
00:19:28.640 --> 00:19:31.640
<v Speaker 2>Definitely. Arrays and hashes are workhourses in Ruby, and they're

389
00:19:31.720 --> 00:19:32.960
<v Speaker 2>very flexible.

390
00:19:32.599 --> 00:19:35.480
<v Speaker 1>So a rays more than just lists much more.

391
00:19:35.519 --> 00:19:38.640
<v Speaker 2>You've got basic access with indexes first, last getting the

392
00:19:38.720 --> 00:19:41.599
<v Speaker 2>length or size. But sorting is where things get interesting,

393
00:19:41.839 --> 00:19:43.480
<v Speaker 2>especially sortby Sortpye.

394
00:19:43.680 --> 00:19:45.160
<v Speaker 1>You mentioned the short seat transform.

395
00:19:45.440 --> 00:19:49.440
<v Speaker 2>Yeah, it's a pattern sort be often implements. Imagine sorting

396
00:19:49.440 --> 00:19:52.839
<v Speaker 2>files by size, calling filed out size for every comparison

397
00:19:52.920 --> 00:19:55.839
<v Speaker 2>during the sort can be slow if you have many.

398
00:19:55.640 --> 00:19:57.799
<v Speaker 1>Files right, lots of disc access.

399
00:19:57.480 --> 00:20:01.960
<v Speaker 2>Maybe exactly Sort b file file file calculates the size

400
00:20:02.000 --> 00:20:04.599
<v Speaker 2>once for each file, creating a temporary list of sizes.

401
00:20:05.119 --> 00:20:07.480
<v Speaker 2>It then sorts based on those cheap to compare sizes

402
00:20:07.559 --> 00:20:10.799
<v Speaker 2>and uses that order to arrange the original fileist. It

403
00:20:10.880 --> 00:20:13.519
<v Speaker 2>dramatically speeds up sorts based on expensive calculation.

404
00:20:13.640 --> 00:20:16.839
<v Speaker 1>That's really clever. Optimize the expensive part finding stuff in

405
00:20:16.960 --> 00:20:18.119
<v Speaker 1>arrays lots of ways.

406
00:20:18.519 --> 00:20:21.680
<v Speaker 2>Find gets the first matching element, findal or its alias

407
00:20:21.680 --> 00:20:23.400
<v Speaker 2>select gets all matching elements.

408
00:20:23.599 --> 00:20:26.200
<v Speaker 1>And then there's gp g rep like the command line tool.

409
00:20:26.359 --> 00:20:29.119
<v Speaker 2>Similar idea, but it uses that triple epls operator again,

410
00:20:29.160 --> 00:20:30.720
<v Speaker 2>so you can g rep an array not just with

411
00:20:30.759 --> 00:20:33.240
<v Speaker 2>a regular expression, but also with a class array dot

412
00:20:33.319 --> 00:20:37.000
<v Speaker 2>grip string arrange a ray dot grap one takes zero

413
00:20:37.200 --> 00:20:39.160
<v Speaker 2>or anything that responds meaningfully.

414
00:20:38.720 --> 00:20:43.359
<v Speaker 1>To a pops up again. Versatile arrays as stacks and ques.

415
00:20:43.200 --> 00:20:46.039
<v Speaker 2>Yep classic use case. For a stack last in first out,

416
00:20:46.160 --> 00:20:47.720
<v Speaker 2>you use push to add to the end and pop

417
00:20:47.759 --> 00:20:48.519
<v Speaker 2>to remove from the end.

418
00:20:48.519 --> 00:20:49.640
<v Speaker 1>Push pop at the end.

419
00:20:49.759 --> 00:20:52.960
<v Speaker 2>For a Q first in first out, you use push

420
00:20:53.319 --> 00:20:56.160
<v Speaker 2>or unshift to add and shift to remove from the beginning.

421
00:20:56.279 --> 00:20:58.839
<v Speaker 1>Shift from the beginning. Got to keep those straight.

422
00:20:58.680 --> 00:21:02.519
<v Speaker 2>Yeah, push pop For stacks shift unshift often involved in cues.

423
00:21:03.039 --> 00:21:04.920
<v Speaker 2>Just remember where things are added and removed.

424
00:21:05.000 --> 00:21:08.119
<v Speaker 1>Ruby rays can also do set operations directly.

425
00:21:08.480 --> 00:21:11.440
<v Speaker 2>You can use for union and for intersection and for

426
00:21:11.559 --> 00:21:15.519
<v Speaker 2>difference right on array objects, there are also methods like

427
00:21:15.599 --> 00:21:19.759
<v Speaker 2>subset and super set available if you require set, although

428
00:21:19.799 --> 00:21:22.279
<v Speaker 2>for heavy set work using the actual set class is

429
00:21:22.359 --> 00:21:22.920
<v Speaker 2>usually better.

430
00:21:23.000 --> 00:21:26.559
<v Speaker 1>Okay, And that idea about sparse matrices using hashes instead.

431
00:21:26.759 --> 00:21:29.319
<v Speaker 2>Right, If you have an array where most elements are

432
00:21:29.400 --> 00:21:32.440
<v Speaker 2>nil because you've only assigned values at say index zero

433
00:21:32.480 --> 00:21:34.680
<v Speaker 2>and index one million, that can waste a lot of

434
00:21:34.720 --> 00:21:35.799
<v Speaker 2>memory holding all those.

435
00:21:35.720 --> 00:21:36.960
<v Speaker 1>Nils well empty slot.

436
00:21:37.119 --> 00:21:39.839
<v Speaker 2>Yeah, a hash with a default value like hash dot

437
00:21:39.880 --> 00:21:42.759
<v Speaker 2>new can be much more memory efficient. You only store

438
00:21:42.799 --> 00:21:45.759
<v Speaker 2>the key value pairs that actually exist. Accessing a non

439
00:21:45.799 --> 00:21:48.440
<v Speaker 2>existent key just gives you the default zero instead of

440
00:21:48.519 --> 00:21:52.000
<v Speaker 2>nil or an error smart alternative. Speaking of hashes, there

441
00:21:52.039 --> 00:21:55.599
<v Speaker 2>are your standard dynamic key value pairs, and as we

442
00:21:55.759 --> 00:21:58.480
<v Speaker 2>just said, using hash dot new value is great for

443
00:21:58.480 --> 00:22:01.519
<v Speaker 2>setting a default value for keys that haven't been assigned yet.

444
00:22:01.680 --> 00:22:04.319
<v Speaker 2>Makes handling counters or accumulating values.

445
00:22:03.960 --> 00:22:05.359
<v Speaker 1>Really easy and iterating.

446
00:22:05.599 --> 00:22:09.799
<v Speaker 2>You can easily iterate over keys skis dot each values

447
00:22:09.920 --> 00:22:13.559
<v Speaker 2>values dot each or key value pairs together not each

448
00:22:13.799 --> 00:22:16.240
<v Speaker 2>key value. Very straightforward.

449
00:22:16.440 --> 00:22:19.240
<v Speaker 1>Okay. Let's move on to symbols and ranges distinctive Ruby

450
00:22:19.279 --> 00:22:23.359
<v Speaker 1>tools symbols first, like dot my symbol. What are they really?

451
00:22:23.559 --> 00:22:26.920
<v Speaker 2>They're often described as immutable identifiers. Think of them like

452
00:22:27.160 --> 00:22:31.839
<v Speaker 2>lightweight guaranteed unique names. They're commonly used as keys and hashes,

453
00:22:32.039 --> 00:22:35.319
<v Speaker 2>especially an older rubycun or when performance is critical and

454
00:22:35.400 --> 00:22:38.039
<v Speaker 2>for things like method names, pass to functions or with

455
00:22:38.119 --> 00:22:39.440
<v Speaker 2>a problem. Are dot my symbol?

456
00:22:39.559 --> 00:22:42.039
<v Speaker 1>So like strings, but different.

457
00:22:41.799 --> 00:22:43.920
<v Speaker 2>Kind of They look like strings, but they don't inherit

458
00:22:43.960 --> 00:22:46.400
<v Speaker 2>from string. They have their own class symbol. They are

459
00:22:46.440 --> 00:22:49.680
<v Speaker 2>guaranteed to be unique. The symbol dot name always refers

460
00:22:49.720 --> 00:22:52.400
<v Speaker 2>to the exact same object in memory, whereas the string

461
00:22:52.519 --> 00:22:54.279
<v Speaker 2>name could be a new object each time.

462
00:22:54.440 --> 00:22:58.440
<v Speaker 1>Oh okay, performance benefits sometimes. Yeah, and that symbol table idea.

463
00:22:58.680 --> 00:23:01.000
<v Speaker 2>Yeah, people sometimes talk about it, but it's an internal

464
00:23:01.039 --> 00:23:05.400
<v Speaker 2>implementation detail. As Ruby programmers, we don't directly manipulate some

465
00:23:05.519 --> 00:23:09.960
<v Speaker 2>global symbol table. Ruby manages how symbols are stored efficiently

466
00:23:10.000 --> 00:23:10.680
<v Speaker 2>behind the scenes.

467
00:23:10.799 --> 00:23:14.680
<v Speaker 1>Got it ranges that versus desk simple but crucial distinction.

468
00:23:15.119 --> 00:23:19.039
<v Speaker 2>Two darts creates an inclusive range, so five point on

469
00:23:19.119 --> 00:23:22.839
<v Speaker 2>air includes both five and ten. Three dots creates an

470
00:23:22.839 --> 00:23:26.759
<v Speaker 2>exclusive range, meaning it excludes the end value. Five pointner

471
00:23:27.039 --> 00:23:29.440
<v Speaker 2>includes five up to nine, but not ten.

472
00:23:29.599 --> 00:23:30.640
<v Speaker 1>Easy to mix up.

473
00:23:30.759 --> 00:23:33.440
<v Speaker 2>Very always double check if you need inclusive or exclusive,

474
00:23:33.480 --> 00:23:35.480
<v Speaker 2>then there's that quirky flip flop.

475
00:23:35.240 --> 00:23:37.559
<v Speaker 1>Operator pearl inheritance exactly.

476
00:23:37.519 --> 00:23:40.680
<v Speaker 2>Using the range operator, or inside a conditional like an

477
00:23:40.720 --> 00:23:43.720
<v Speaker 2>if statement, or often within loops reading files line by line,

478
00:23:44.039 --> 00:23:45.319
<v Speaker 2>it acts like a state.

479
00:23:45.119 --> 00:23:47.319
<v Speaker 1>Machine toggle a toggle how.

480
00:23:47.440 --> 00:23:49.480
<v Speaker 2>The condition is false until the left side of the

481
00:23:49.559 --> 00:23:52.359
<v Speaker 2>range becomes true. Then the condition becomes true and stays

482
00:23:52.400 --> 00:23:54.519
<v Speaker 2>true until the right side becomes true, at which point

483
00:23:54.559 --> 00:23:57.599
<v Speaker 2>it becomes false again on that same evaluation or the next.

484
00:23:57.359 --> 00:23:59.559
<v Speaker 1>Depending on the yeah okay use case.

485
00:24:00.000 --> 00:24:03.680
<v Speaker 2>The classic example is extracting text between specific markers and

486
00:24:03.720 --> 00:24:06.519
<v Speaker 2>a file, like getting everything between a begin line and

487
00:24:06.559 --> 00:24:09.359
<v Speaker 2>an end line. It works, but the book admits it's

488
00:24:09.400 --> 00:24:13.000
<v Speaker 2>unintuitive and often a more explicit state machine approach.

489
00:24:12.720 --> 00:24:15.799
<v Speaker 1>Is clear probably good advice. Can you make ranges of anything?

490
00:24:15.839 --> 00:24:18.240
<v Speaker 2>Pretty much anything that knows how to compare itself and

491
00:24:18.319 --> 00:24:21.160
<v Speaker 2>step to the next element. The book shows an example

492
00:24:21.200 --> 00:24:23.799
<v Speaker 2>with a custom Roman numeral class, creating a range of

493
00:24:23.880 --> 00:24:24.599
<v Speaker 2>Roman numerals.

494
00:24:24.640 --> 00:24:27.640
<v Speaker 1>Cool okay. Finally, in this section time and date, how

495
00:24:27.640 --> 00:24:28.480
<v Speaker 1>does ruby amble as.

496
00:24:28.759 --> 00:24:30.839
<v Speaker 2>Robustly With the time class, you can get the current

497
00:24:30.880 --> 00:24:34.559
<v Speaker 2>time with time dot. Now you can create specific times,

498
00:24:34.640 --> 00:24:37.400
<v Speaker 2>using time dot local for your system's time zone, or

499
00:24:37.759 --> 00:24:41.839
<v Speaker 2>time dot UTC or time dot GM for Coordinated Universal time.

500
00:24:41.680 --> 00:24:43.440
<v Speaker 1>And formatting them making them look nice.

501
00:24:43.519 --> 00:24:45.759
<v Speaker 2>That's where streff time comes in. It's super powerful. You

502
00:24:45.799 --> 00:24:48.680
<v Speaker 2>pass it format codes like percent for the four digit year,

503
00:24:48.799 --> 00:24:51.440
<v Speaker 2>percent for the month, number, percent for the day, percent

504
00:24:51.480 --> 00:24:54.000
<v Speaker 2>for twenty four hour clock, percent for twelve hour, percent

505
00:24:54.039 --> 00:24:58.160
<v Speaker 2>for AMPM, percent for full weekday name, percent for abbreviated.

506
00:24:58.559 --> 00:25:01.720
<v Speaker 2>Tons of options. To get exact the string representation, you need.

507
00:25:01.759 --> 00:25:03.640
<v Speaker 1>Very flexible calculating differences.

508
00:25:04.039 --> 00:25:07.720
<v Speaker 2>Simple subtraction. Subtracting one time object from another gives you

509
00:25:07.759 --> 00:25:10.400
<v Speaker 2>the difference in seconds as a float. You can then

510
00:25:10.480 --> 00:25:13.839
<v Speaker 2>easily convert that float into days, hours, minutes, et cetera

511
00:25:14.000 --> 00:25:15.240
<v Speaker 2>with some basic arithmetic.

512
00:25:15.440 --> 00:25:19.119
<v Speaker 1>What about really old dates before nineteen seventy.

513
00:25:19.000 --> 00:25:23.799
<v Speaker 2>For dates, especially historical ones that precede midnight GMT January first,

514
00:25:23.960 --> 00:25:27.079
<v Speaker 2>nineteen seventy, the start of the Unix epoch, which time

515
00:25:27.160 --> 00:25:30.400
<v Speaker 2>is often based on. Ruby provides the date class. It

516
00:25:30.440 --> 00:25:34.400
<v Speaker 2>handles a much wider range of dates accurately requires required date.

517
00:25:34.160 --> 00:25:37.039
<v Speaker 1>Read for historical stuff, and the book mentions calculating Easter.

518
00:25:37.240 --> 00:25:39.920
<v Speaker 2>Yeah, just as a fun example of a complex date calculation.

519
00:25:40.319 --> 00:25:43.079
<v Speaker 2>Easter's date depends on the lunar cycle, making it tricky.

520
00:25:43.400 --> 00:25:45.759
<v Speaker 2>The book notes that a standard algorithm for it is

521
00:25:45.759 --> 00:25:48.759
<v Speaker 2>available in Ruby, highlighting that the language can handle these

522
00:25:48.839 --> 00:25:51.200
<v Speaker 2>kinds of intricate calendar computations.

523
00:25:51.200 --> 00:25:54.319
<v Speaker 1>The classic programming puzzle, Okay, let's broaden out now to

524
00:25:54.400 --> 00:25:58.119
<v Speaker 1>interacting with the world outside the program's memory IO more

525
00:25:58.160 --> 00:26:02.160
<v Speaker 1>advanced data structures, and that topic concurrency.

526
00:26:01.759 --> 00:26:05.160
<v Speaker 2>Right, So input output IO. The foundation in Ruby is

527
00:26:05.200 --> 00:26:09.000
<v Speaker 2>the ioclass. Everything involving reading from or writing to external

528
00:26:09.000 --> 00:26:11.839
<v Speaker 2>sources like files or network sockets, builds.

529
00:26:11.519 --> 00:26:13.799
<v Speaker 1>On IO, and file is related.

530
00:26:13.839 --> 00:26:17.359
<v Speaker 2>How file inherits directly from IO, so all the general

531
00:26:17.400 --> 00:26:21.279
<v Speaker 2>iomethods work on files, plus file ads methods specific to

532
00:26:21.480 --> 00:26:25.359
<v Speaker 2>filesystem operations like opening files exactly. You use file dot

533
00:26:25.400 --> 00:26:28.279
<v Speaker 2>open with different modes R for read only, default, W

534
00:26:28.519 --> 00:26:31.400
<v Speaker 2>for write only, trunk kates for creates, a for upend only,

535
00:26:31.920 --> 00:26:35.359
<v Speaker 2>R plus for readwrit starting at the beginning W plus

536
00:26:35.440 --> 00:26:38.960
<v Speaker 2>or ReadWrite shuncating first, A plus for readwrit appending first.

537
00:26:39.640 --> 00:26:42.440
<v Speaker 1>Lots of control and moving around inside a file that's.

538
00:26:42.279 --> 00:26:45.519
<v Speaker 2>Seeking, you use the seek method. You can seek relative

539
00:26:45.519 --> 00:26:48.440
<v Speaker 2>to the beginning I seek set the current position, ioc

540
00:26:48.559 --> 00:26:52.400
<v Speaker 2>cur or the end iosecend lets you jump to specific

541
00:26:52.440 --> 00:26:53.240
<v Speaker 2>bite offsets.

542
00:26:53.400 --> 00:26:56.880
<v Speaker 1>What about file metadata ownership permissions Yep.

543
00:26:56.920 --> 00:26:58.920
<v Speaker 2>You can use challenge to change the owner in group

544
00:26:58.960 --> 00:27:02.240
<v Speaker 2>and chamod to change the permissions like read, write execute.

545
00:27:02.400 --> 00:27:06.119
<v Speaker 2>You can also check file characteristics using methods like exist, size, diirectory,

546
00:27:06.160 --> 00:27:08.519
<v Speaker 2>dot pipe or teddy set a terminal.

547
00:27:08.680 --> 00:27:11.119
<v Speaker 1>And for common tasks like copying or moving.

548
00:27:10.880 --> 00:27:13.039
<v Speaker 2>Files, the fileutols module is your friend.

549
00:27:13.039 --> 00:27:13.319
<v Speaker 1>There.

550
00:27:13.480 --> 00:27:16.839
<v Speaker 2>It provides higher levels safer methods like file youutails dot copy,

551
00:27:16.839 --> 00:27:19.960
<v Speaker 2>file youtools dot move, fileutols dot mk dirt makes parent

552
00:27:19.960 --> 00:27:23.599
<v Speaker 2>directories too, and fileutols dot safe on the link delete safely,

553
00:27:24.000 --> 00:27:25.480
<v Speaker 2>much easier than doing it manually.

554
00:27:25.599 --> 00:27:27.759
<v Speaker 1>Okay, how about embedding data in the script?

555
00:27:27.839 --> 00:27:31.400
<v Speaker 2>AH the ND directive. If you put ND on a

556
00:27:31.440 --> 00:27:34.480
<v Speaker 2>line by itself in your script, everything after that line

557
00:27:34.519 --> 00:27:36.920
<v Speaker 2>is ignored by the Ruby interpreter, but becomes available to

558
00:27:36.960 --> 00:27:40.680
<v Speaker 2>your script through the special data constant data. Yeah. Data

559
00:27:40.720 --> 00:27:44.559
<v Speaker 2>acts like an openio object, specifically a file object positioned

560
00:27:44.559 --> 00:27:46.559
<v Speaker 2>at the start of that embedded data. You can just

561
00:27:46.599 --> 00:27:49.279
<v Speaker 2>read from data like you'd read from any file. Great

562
00:27:49.279 --> 00:27:52.279
<v Speaker 2>for including templates or test data directly in a script.

563
00:27:52.480 --> 00:27:54.799
<v Speaker 2>Also file gives you the path to the current file,

564
00:27:54.799 --> 00:27:56.720
<v Speaker 2>which you can then open and read if needed.

565
00:27:56.880 --> 00:27:59.839
<v Speaker 1>Clever now saving Ruby objects.

566
00:27:59.279 --> 00:28:03.720
<v Speaker 2>Persistence two main ways mentioned. Marshall is for Ruby specific serialization.

567
00:28:04.240 --> 00:28:06.720
<v Speaker 2>It dumps a Ruby object hierarchy into a byte stream

568
00:28:06.759 --> 00:28:08.400
<v Speaker 2>that can be saved to a file or sent over

569
00:28:08.440 --> 00:28:11.000
<v Speaker 2>a network, and then loaded back into an identical Ruby

570
00:28:11.000 --> 00:28:14.440
<v Speaker 2>object later using Marshal dot load. Great for saving program

571
00:28:14.559 --> 00:28:15.839
<v Speaker 2>state or deep copying.

572
00:28:15.599 --> 00:28:17.400
<v Speaker 1>Objects, but only Ruby can read it.

573
00:28:17.559 --> 00:28:22.160
<v Speaker 2>Generally yes for human readable serialization or for interoperability with

574
00:28:22.200 --> 00:28:26.160
<v Speaker 2>other languages. Yamel yamal Ain't markup language is very popular

575
00:28:26.160 --> 00:28:29.960
<v Speaker 2>in the Ruby world. It represents objects using indentation and

576
00:28:30.039 --> 00:28:34.200
<v Speaker 2>simple text, often used for configuration, files and databases. Ruby

577
00:28:34.240 --> 00:28:38.000
<v Speaker 2>has excellent database support. The book mentions squill three as

578
00:28:38.039 --> 00:28:41.319
<v Speaker 2>a simple file based option. And then there's the concept

579
00:28:41.400 --> 00:28:45.440
<v Speaker 2>of orm's object relational mappers libraries like active record from

580
00:28:45.519 --> 00:28:48.799
<v Speaker 2>rails or seql map database tables and rows directly into

581
00:28:48.920 --> 00:28:52.920
<v Speaker 2>Ruby classes and objects, making database interaction feel very natural

582
00:28:53.000 --> 00:28:53.960
<v Speaker 2>within Ruby code.

583
00:28:54.039 --> 00:28:57.759
<v Speaker 1>Okay, beyond standard arrays and hashes, what advanced structures does

584
00:28:57.839 --> 00:28:58.440
<v Speaker 1>Ruby offer?

585
00:28:58.599 --> 00:29:01.839
<v Speaker 2>The standard library includes set class, which is optimized for

586
00:29:02.000 --> 00:29:06.000
<v Speaker 2>mathematical set operations, checking membership, unions, intersections when you need

587
00:29:06.039 --> 00:29:08.519
<v Speaker 2>a collection of unique items and don't care about order.

588
00:29:08.559 --> 00:29:10.799
<v Speaker 1>Like unique IDs or tags exactly.

589
00:29:11.000 --> 00:29:14.000
<v Speaker 2>And while arrays can act as staxques, there are also

590
00:29:14.240 --> 00:29:17.720
<v Speaker 2>dedicated QUE and size q classes in the standard library,

591
00:29:17.920 --> 00:29:19.599
<v Speaker 2>primarily for concurrent programming.

592
00:29:19.720 --> 00:29:22.240
<v Speaker 1>Q and size Q. What's special about them.

593
00:29:22.200 --> 00:29:25.400
<v Speaker 2>They are thread safe. Multiple threads can add OnCore, push

594
00:29:25.519 --> 00:29:29.079
<v Speaker 2>and remove, deck or pop or shift items without corrupting

595
00:29:29.119 --> 00:29:33.079
<v Speaker 2>the queue's internal state. Size Q adds a maximum size limit,

596
00:29:33.359 --> 00:29:34.279
<v Speaker 2>useful for flow.

597
00:29:34.119 --> 00:29:38.440
<v Speaker 1>Control, thread safe okay important for concurrency binary trees.

598
00:29:38.920 --> 00:29:43.000
<v Speaker 2>The book discusses them useful for keeping data sorted, efficient searching,

599
00:29:43.200 --> 00:29:46.920
<v Speaker 2>logarithmic time, and different traversal orders in order, pre order

600
00:29:47.000 --> 00:29:50.160
<v Speaker 2>or post order, but it also realistically notes that for

601
00:29:50.279 --> 00:29:53.400
<v Speaker 2>many common lookup tasks, a hash or even an external

602
00:29:53.480 --> 00:29:56.920
<v Speaker 2>database table will be preferable due to simplicity and often

603
00:29:56.960 --> 00:29:58.200
<v Speaker 2>better practical performance.

604
00:29:58.200 --> 00:29:59.960
<v Speaker 1>In Ruby, good context.

605
00:29:59.640 --> 00:30:03.160
<v Speaker 2>And graphs are covered as ways to model connections nodes

606
00:30:03.160 --> 00:30:07.359
<v Speaker 2>connected by edges think social networks, roadmaps, network topologies. They

607
00:30:07.400 --> 00:30:11.039
<v Speaker 2>can be undirected edges go both ways, directed digrass edges

608
00:30:11.079 --> 00:30:14.440
<v Speaker 2>have direction, or weighted edges have a cost or distance

609
00:30:14.799 --> 00:30:17.119
<v Speaker 2>powerful for representing complex relationships.

610
00:30:17.200 --> 00:30:20.200
<v Speaker 1>Okay, now for the really complex part, threads and concurrency

611
00:30:20.200 --> 00:30:22.039
<v Speaker 1>making the computer do multiple things at once.

612
00:30:22.480 --> 00:30:26.799
<v Speaker 2>Right, it's crucial to distinguish threads from processes. Processes have

613
00:30:26.839 --> 00:30:30.559
<v Speaker 2>separate memory spaces. They're isolated. Threads exist within a process

614
00:30:30.599 --> 00:30:32.079
<v Speaker 2>and share the same memory space.

615
00:30:32.359 --> 00:30:35.519
<v Speaker 1>Shared memory sounds like potential for problems.

616
00:30:35.759 --> 00:30:39.400
<v Speaker 2>That's the main challenge. But first, creating threads is easy.

617
00:30:39.559 --> 00:30:43.039
<v Speaker 2>Thread dot new dot dot new dot code to run

618
00:30:43.079 --> 00:30:46.440
<v Speaker 2>and thread for thread specific data that shouldn't clash with

619
00:30:46.480 --> 00:30:50.279
<v Speaker 2>other threads. You can use thread local variables thread dot

620
00:30:50.319 --> 00:30:53.519
<v Speaker 2>current dot myvar eels value.

621
00:30:53.240 --> 00:30:56.079
<v Speaker 1>Thread dot current and these variables stick around.

622
00:30:56.200 --> 00:30:59.720
<v Speaker 2>Interestingly, yes, the booknotes they persist even after the thread

623
00:30:59.759 --> 00:31:03.839
<v Speaker 2>finish associated with the thread object itself. Useful maybe for

624
00:31:03.880 --> 00:31:05.480
<v Speaker 2>post mortem debugging or logging.

625
00:31:05.519 --> 00:31:07.720
<v Speaker 1>But the shared memory problem the when problem.

626
00:31:07.880 --> 00:31:11.079
<v Speaker 2>Yeah, If multiple threads access and modify the same shared

627
00:31:11.160 --> 00:31:15.000
<v Speaker 2>variable like a counter, without coordination, the order of operations

628
00:31:15.000 --> 00:31:18.279
<v Speaker 2>becomes unpredictable due to how the operating system schedules threads.

629
00:31:18.680 --> 00:31:21.519
<v Speaker 2>This leads to race conditions and random behavior, making your

630
00:31:21.559 --> 00:31:22.799
<v Speaker 2>program unreliable.

631
00:31:22.920 --> 00:31:23.799
<v Speaker 1>Just how do you coordinate?

632
00:31:24.039 --> 00:31:27.400
<v Speaker 2>The primary tool is a mutex short For mutual exclusion,

633
00:31:27.880 --> 00:31:30.839
<v Speaker 2>you create a mutex object and then use its synchronized

634
00:31:30.880 --> 00:31:36.440
<v Speaker 2>method mimutex dot synchronize critical code. Here, only one thread

635
00:31:36.480 --> 00:31:39.119
<v Speaker 2>can be executing the code inside that block at any

636
00:31:39.160 --> 00:31:42.640
<v Speaker 2>given time for that specific mutech it locks that section exactly.

637
00:31:43.000 --> 00:31:46.720
<v Speaker 2>It ensures atomic access to the shared resources within the block,

638
00:31:46.839 --> 00:31:48.200
<v Speaker 2>preventing race conditions.

639
00:31:48.559 --> 00:31:50.920
<v Speaker 1>What about common patterns like producer consumer.

640
00:31:51.000 --> 00:31:54.000
<v Speaker 2>That's where size q shines one thread the producer calls

641
00:31:54.000 --> 00:31:56.079
<v Speaker 2>on to add items to the queue, and another thread

642
00:31:56.119 --> 00:31:59.680
<v Speaker 2>the consumer calls deck to remove them. Sized q handles

643
00:31:59.680 --> 00:32:02.480
<v Speaker 2>all the locking and waiting internally, making it a safe

644
00:32:02.480 --> 00:32:05.200
<v Speaker 2>and efficient way to pass data between threads. If the

645
00:32:05.240 --> 00:32:07.799
<v Speaker 2>queue is full, the producer waits. If it's empty, the

646
00:32:07.839 --> 00:32:08.640
<v Speaker 2>consumer weights.

647
00:32:08.960 --> 00:32:12.359
<v Speaker 1>Built in solution nice any more complex problems.

648
00:32:12.039 --> 00:32:15.200
<v Speaker 2>The book mentions the classic dining philosopher's problem as an

649
00:32:15.200 --> 00:32:20.640
<v Speaker 2>example requiring more advanced synchronization, often involving condition variable alongside

650
00:32:20.640 --> 00:32:24.599
<v Speaker 2>a mutex. Condition variables allow threads to wait efficiently for

651
00:32:24.640 --> 00:32:28.480
<v Speaker 2>a specific condition to become true before proceeding. It solves

652
00:32:28.480 --> 00:32:32.119
<v Speaker 2>potential deadlocks, but can be complex and, as noted, potentially

653
00:32:32.200 --> 00:32:34.440
<v Speaker 2>unfair in scheduling complex stuff.

654
00:32:34.559 --> 00:32:36.319
<v Speaker 1>What about operations that take too long.

655
00:32:36.359 --> 00:32:39.559
<v Speaker 2>There's timeout dot timeout seconds. It runs the block but

656
00:32:39.640 --> 00:32:42.240
<v Speaker 2>raises a timeout error if it doesn't finish within the

657
00:32:42.279 --> 00:32:45.279
<v Speaker 2>specified number of seconds, useful for preventing hangs.

658
00:32:45.559 --> 00:32:48.400
<v Speaker 1>Timeout dot error is that a standard error.

659
00:32:48.640 --> 00:32:51.160
<v Speaker 2>Crucially, no, it does not inherit from standard error, So

660
00:32:51.200 --> 00:32:53.279
<v Speaker 2>if you have a generic rescue standard error, you will

661
00:32:53.279 --> 00:32:56.720
<v Speaker 2>not touch timeout. You have to explicitly rescue timeout dot

662
00:32:56.839 --> 00:32:58.759
<v Speaker 2>error a common gotcha good tip.

663
00:32:59.079 --> 00:33:01.039
<v Speaker 1>Okay, let's bring it home by looking at Ruby in

664
00:33:01.119 --> 00:33:05.319
<v Speaker 1>the real world web development GUIs and the tools developers

665
00:33:05.359 --> 00:33:05.839
<v Speaker 1>use daily.

666
00:33:06.119 --> 00:33:09.240
<v Speaker 2>Ruby definitely made a huge splash in web development. The

667
00:33:09.319 --> 00:33:13.759
<v Speaker 2>foundation is HTTP, just a simple text protocol over TCP sockets.

668
00:33:14.119 --> 00:33:16.839
<v Speaker 2>Ruby can handle this directly, but you usually use frameworks

669
00:33:17.279 --> 00:33:21.480
<v Speaker 2>like Rack. Rack is fundamental but usually invisible to application developers.

670
00:33:21.759 --> 00:33:24.960
<v Speaker 2>It provides a standard interface and API between Ruby web

671
00:33:25.000 --> 00:33:28.799
<v Speaker 2>servers like Puma or Unicorn and Ruby web frameworks like

672
00:33:28.880 --> 00:33:31.640
<v Speaker 2>Rails or Sinatra. It's the glue, as the book says,

673
00:33:31.720 --> 00:33:33.559
<v Speaker 2>mostly for framework developers, so.

674
00:33:33.440 --> 00:33:36.799
<v Speaker 1>Most people use something built on Rack like Rails exactly.

675
00:33:36.960 --> 00:33:41.880
<v Speaker 2>Rails is the big full stack MVC framework model view.

676
00:33:41.720 --> 00:33:43.319
<v Speaker 1>Controller break that down quickly.

677
00:33:43.359 --> 00:33:48.279
<v Speaker 2>Sure controllers handle incoming web requests, process parameters, interact with models,

678
00:33:48.440 --> 00:33:51.359
<v Speaker 2>and decide what response to send, often rendering a view

679
00:33:51.640 --> 00:33:54.559
<v Speaker 2>like an htmail template. You might see render in line

680
00:33:54.799 --> 00:33:58.440
<v Speaker 2>hello for a simple response. Routing maps URLs like users

681
00:33:58.440 --> 00:34:01.480
<v Speaker 2>dot id to specific control actions users.

682
00:34:01.160 --> 00:34:03.599
<v Speaker 1>Tech show, and the model part data.

683
00:34:03.240 --> 00:34:05.680
<v Speaker 2>That's typically handled by Active Record and rails. It's the

684
00:34:05.799 --> 00:34:09.039
<v Speaker 2>ORM we mentioned mapping database tables like users to Ruby

685
00:34:09.039 --> 00:34:12.719
<v Speaker 2>classes user. It makes interacting with SQL databases feel very

686
00:34:12.760 --> 00:34:15.840
<v Speaker 2>Ruby like. Other ORMs exist for no SQL databases too,

687
00:34:15.920 --> 00:34:17.199
<v Speaker 2>like mongoid for Mango dB.

688
00:34:17.559 --> 00:34:19.480
<v Speaker 1>Rails also handles front end stuff.

689
00:34:19.320 --> 00:34:22.960
<v Speaker 2>Yeah through its asset pipeline. It manages and processes CSS,

690
00:34:23.000 --> 00:34:27.480
<v Speaker 2>often using SaaS preprocessing and JavaScript or alternatives like Coffee

691
00:34:27.480 --> 00:34:30.199
<v Speaker 2>script to build the rich interactive parts of a web

692
00:34:30.239 --> 00:34:32.320
<v Speaker 2>application that run in the user's browser.

693
00:34:32.400 --> 00:34:35.639
<v Speaker 1>Okay, web services and APIs Jason versus XML.

694
00:34:35.679 --> 00:34:38.800
<v Speaker 2>Just on JavaScript object notation has largely one out over

695
00:34:38.960 --> 00:34:42.480
<v Speaker 2>XML for epis these days. It's just more terse, minimal,

696
00:34:42.599 --> 00:34:46.400
<v Speaker 2>easier for browsers and humans to parse. Most modern web

697
00:34:46.400 --> 00:34:50.639
<v Speaker 2>development involves consuming or providing Jason, APIs and rest rest.

698
00:34:50.800 --> 00:34:55.519
<v Speaker 2>Representational state transfer is an architectural style for designing networked applications,

699
00:34:55.559 --> 00:35:01.840
<v Speaker 2>particularly web services. It emphasizes statelessness, standard h GDP methods get, post,

700
00:35:01.880 --> 00:35:06.119
<v Speaker 2>put delete for cred operations, and predictable resource URLs. RAILS

701
00:35:06.119 --> 00:35:09.239
<v Speaker 2>conventions heavily lean on rest principles. Making API design more

702
00:35:09.280 --> 00:35:10.360
<v Speaker 2>consistent makes sense.

703
00:35:10.480 --> 00:35:12.599
<v Speaker 1>Now gis desktop apps with Ruby.

704
00:35:12.719 --> 00:35:16.000
<v Speaker 2>It's possible, though maybe less common than web apps. GI

705
00:35:16.079 --> 00:35:18.840
<v Speaker 2>design itself is challenging. The book highlights Shoes for as

706
00:35:18.840 --> 00:35:23.760
<v Speaker 2>a uniquely rubysd option. Shoes It's known for being incredibly

707
00:35:23.800 --> 00:35:26.599
<v Speaker 2>simple to learn and use, focusing on ease for small

708
00:35:26.639 --> 00:35:31.119
<v Speaker 2>graphical applications. It can even package apps as standalone executables.

709
00:35:31.679 --> 00:35:34.559
<v Speaker 2>The latest version uses j Ruby running on the Java

710
00:35:34.639 --> 00:35:37.559
<v Speaker 2>Virtual Machine, which helps with cross platform.

711
00:35:37.079 --> 00:35:39.000
<v Speaker 1>Compatibility any other options.

712
00:35:39.199 --> 00:35:42.079
<v Speaker 2>Ruby tech is mentioned as an older, very stable and

713
00:35:42.159 --> 00:35:47.000
<v Speaker 2>portable binding to the classic TK toolkit. It's showing its age, perhaps,

714
00:35:47.039 --> 00:35:50.679
<v Speaker 2>but it works. There are also bindings for GTK Ruby,

715
00:35:50.679 --> 00:35:54.280
<v Speaker 2>GTT three and qt qt Ruby for integrating with those

716
00:35:54.320 --> 00:35:55.639
<v Speaker 2>popular desktop environments.

717
00:35:55.880 --> 00:35:59.199
<v Speaker 1>Okay, let's stuff tools. What helps Ruby developers get work

718
00:35:59.239 --> 00:36:00.639
<v Speaker 1>done is essential.

719
00:36:00.679 --> 00:36:04.239
<v Speaker 2>It's Ruby's version of make you define tasks like running tests,

720
00:36:04.280 --> 00:36:07.480
<v Speaker 2>migrating databases, deploying code in a Reek file using Ruby

721
00:36:07.519 --> 00:36:11.800
<v Speaker 2>syntax and then run them from the command line, Rake, Test, rakedbtt, Migrate.

722
00:36:11.599 --> 00:36:13.800
<v Speaker 1>Automation Helper. What about interactive shells?

723
00:36:13.960 --> 00:36:16.559
<v Speaker 2>Herb is the built in interactive Ruby shell, great for

724
00:36:16.679 --> 00:36:19.440
<v Speaker 2>quick experiments. You can customize it with a dot rbsh file,

725
00:36:19.800 --> 00:36:23.039
<v Speaker 2>but many developers prefer Pride. Pride better than RB It's

726
00:36:23.159 --> 00:36:28.239
<v Speaker 2>much more powerful, offer syntax highlighting code browsing, better debugging capabilities,

727
00:36:28.360 --> 00:36:32.559
<v Speaker 2>stepping through code, examining state. It's fantastic for exploration and

728
00:36:32.559 --> 00:36:34.000
<v Speaker 2>debugging complex.

729
00:36:33.639 --> 00:36:35.800
<v Speaker 1>Issues and getting help documentation.

730
00:36:36.000 --> 00:36:38.519
<v Speaker 2>The Ray command line tool lets you look up documentation

731
00:36:38.679 --> 00:36:42.639
<v Speaker 2>for Ruby classes, methods, modules, write in your terminal. Super

732
00:36:42.679 --> 00:36:44.360
<v Speaker 2>handy Ray or RAY.

733
00:36:44.239 --> 00:36:46.639
<v Speaker 1>Sharpsort managing different Ruby versions.

734
00:36:46.360 --> 00:36:49.760
<v Speaker 2>Crucial for working on multiple projects. Version managers are key.

735
00:36:50.119 --> 00:36:53.920
<v Speaker 2>The book highlights kruby as a good example. Unlike some others,

736
00:36:53.960 --> 00:36:56.639
<v Speaker 2>it doesn't mess with your CD command or require special

737
00:36:56.679 --> 00:36:59.679
<v Speaker 2>permissions for installing gems, making it simpler and cleaner for

738
00:36:59.679 --> 00:37:03.920
<v Speaker 2>many people. Others like urban v or RVM are also popular.

739
00:37:04.039 --> 00:37:04.920
<v Speaker 1>Testing frameworks.

740
00:37:05.039 --> 00:37:08.239
<v Speaker 2>Testing is huge in the Ruby community. Popular choices include

741
00:37:08.400 --> 00:37:12.320
<v Speaker 2>RSPEC with its behavior driven development style, menatist built into

742
00:37:12.360 --> 00:37:16.280
<v Speaker 2>Ruby's standard library, very flexible, and cucumber for acceptance testing

743
00:37:16.360 --> 00:37:20.480
<v Speaker 2>using natural language, you'll often see assertions like expectant result

744
00:37:20.800 --> 00:37:22.000
<v Speaker 2>to expected.

745
00:37:21.599 --> 00:37:24.239
<v Speaker 1>Value and debugging when tests fail.

746
00:37:24.119 --> 00:37:27.679
<v Speaker 2>Bybug or debug dot or be in newer rubies is

747
00:37:27.719 --> 00:37:31.320
<v Speaker 2>a common debugging gym. You insert by bug or debugger

748
00:37:31.320 --> 00:37:33.800
<v Speaker 2>in your code to set a break point. When the

749
00:37:33.840 --> 00:37:36.039
<v Speaker 2>code hits that point, you get a console where you

750
00:37:36.079 --> 00:37:39.440
<v Speaker 2>can inspect variables, step through execution line by line, see

751
00:37:39.440 --> 00:37:41.280
<v Speaker 2>the call stack, and figure out what's going wrong.

752
00:37:41.519 --> 00:37:43.960
<v Speaker 1>What about performance? Making code faster?

753
00:37:44.559 --> 00:37:48.719
<v Speaker 2>The golden rule heavily emphasized Premature optimization is the root

754
00:37:48.760 --> 00:37:52.559
<v Speaker 2>of all evil and related don't optimize until you measure.

755
00:37:53.039 --> 00:37:56.960
<v Speaker 2>Programmers are notoriously bad at guessing where bottlenecks are. Write clear,

756
00:37:57.039 --> 00:38:00.519
<v Speaker 2>correct code first, then, if needed, use profile tools to

757
00:38:00.599 --> 00:38:03.559
<v Speaker 2>find the actual slow parts and optimize those specifically.

758
00:38:03.639 --> 00:38:07.239
<v Speaker 1>Measure first makes sense. Anything to make debugging output clear.

759
00:38:07.519 --> 00:38:11.079
<v Speaker 2>Yes, the PP library, which stands for pretty print. If

760
00:38:11.079 --> 00:38:13.239
<v Speaker 2>you try to just puts a complex object like a

761
00:38:13.239 --> 00:38:15.280
<v Speaker 2>big hash or a nested array, the output can be

762
00:38:15.320 --> 00:38:17.760
<v Speaker 2>a mess. Require PP and then use PP my object

763
00:38:17.840 --> 00:38:20.960
<v Speaker 2>instead of puts. It formats the output nicely with indentation,

764
00:38:21.159 --> 00:38:23.639
<v Speaker 2>making it much easier to read and understand the structure.

765
00:38:24.000 --> 00:38:25.199
<v Speaker 2>Super useful ep.

766
00:38:25.159 --> 00:38:29.440
<v Speaker 1>For pretty print, Got it any final pointers for resources definitely.

767
00:38:29.760 --> 00:38:33.840
<v Speaker 2>Rubydashlang dot org is the official Ruby website for news, downloads,

768
00:38:33.880 --> 00:38:37.400
<v Speaker 2>community info for documentation, Ruby dash dot dot org and

769
00:38:37.559 --> 00:38:41.440
<v Speaker 2>RDoc dot info are indispensable and for finding learning materials

770
00:38:41.480 --> 00:38:43.320
<v Speaker 2>I want to learn. Ruby dot com is mentioned as

771
00:38:43.360 --> 00:38:44.480
<v Speaker 2>a great curated list.

772
00:38:44.760 --> 00:38:48.039
<v Speaker 1>Wow. Okay, we have covered a ton of ground from

773
00:38:48.119 --> 00:38:52.159
<v Speaker 1>Ruby's core philosophy, that principle of lease, surprise, the quarks

774
00:38:52.199 --> 00:38:54.079
<v Speaker 1>like truthiness, the power.

775
00:38:53.760 --> 00:38:57.960
<v Speaker 2>Of case right through its robust op features, reflection, how

776
00:38:57.960 --> 00:39:01.800
<v Speaker 2>it handles strings, those precise numbers like big decimal.

777
00:39:01.400 --> 00:39:04.519
<v Speaker 1>Collections like a rais and hashes, the unique symbols and ranges,

778
00:39:04.599 --> 00:39:09.760
<v Speaker 1>time handling IO, dealing with concurrency using utex's and queues all.

779
00:39:09.679 --> 00:39:11.760
<v Speaker 2>The way to its strength, and web development with Rack

780
00:39:11.840 --> 00:39:15.079
<v Speaker 2>and rails, GI options like shoes, and the essential development

781
00:39:15.079 --> 00:39:18.400
<v Speaker 2>tools like Rake, Pride, testing frameworks and version managers.

782
00:39:18.480 --> 00:39:20.119
<v Speaker 1>It really gives you a sense of the depth here.

783
00:39:20.239 --> 00:39:24.519
<v Speaker 1>Ruby's simple looking syntax often hides some really sophisticated design.

784
00:39:24.679 --> 00:39:27.000
<v Speaker 2>Absolutely, you've really gotten a glimpse into a language that's

785
00:39:27.039 --> 00:39:28.679
<v Speaker 2>both pragmatic and elegant.

786
00:39:28.920 --> 00:39:31.960
<v Speaker 1>So here's something to think about. What does this Ruby

787
00:39:32.000 --> 00:39:35.079
<v Speaker 1>journey mean for how you approach programming in general? Does

788
00:39:35.079 --> 00:39:39.960
<v Speaker 1>seeing Ruby's embrace of dynamic execution its flexibility change how

789
00:39:40.039 --> 00:39:42.199
<v Speaker 1>you think about building software that needs to adapt.

790
00:39:42.679 --> 00:39:46.039
<v Speaker 2>Yeah, Consider how that ability to define things at run time,

791
00:39:46.119 --> 00:39:49.280
<v Speaker 2>to have the program inspect and even modify itself, allows

792
00:39:49.320 --> 00:39:52.760
<v Speaker 2>developers to push boundaries to build systems that can genuinely

793
00:39:52.840 --> 00:39:56.320
<v Speaker 2>evolve on the fly. What new possibilities does that open

794
00:39:56.400 --> 00:39:56.719
<v Speaker 2>up for you?
