WEBVTT

1
00:00:00.160 --> 00:00:03.279
<v Speaker 1>Welcome to the Deep Dive. The show engineered to cut

2
00:00:03.319 --> 00:00:07.360
<v Speaker 1>through the overwhelming noise of information and deliver the essential

3
00:00:07.360 --> 00:00:10.560
<v Speaker 1>insights you need fast. You know that feeling right you

4
00:00:10.599 --> 00:00:12.199
<v Speaker 1>need to get up to speed on something, but just

5
00:00:12.279 --> 00:00:15.199
<v Speaker 1>don't have time to weighe through hundreds of pages. That's

6
00:00:15.199 --> 00:00:17.760
<v Speaker 1>why we're here today. We're taking a deep dive into

7
00:00:17.760 --> 00:00:21.920
<v Speaker 1>the Ruby programming language, specifically Ruby three point two, and

8
00:00:22.000 --> 00:00:25.719
<v Speaker 1>our guide for this is a really comprehensive source programming

9
00:00:25.879 --> 00:00:29.879
<v Speaker 1>Ruby three point two, The Pragmatic Programmer's Guide, a classic.

10
00:00:29.920 --> 00:00:32.759
<v Speaker 2>Really yeah, it's a fantastic resource, and our missioneer is

11
00:00:32.759 --> 00:00:35.479
<v Speaker 2>pretty clear. We want to pull out the most important bits,

12
00:00:35.960 --> 00:00:38.840
<v Speaker 2>the surprising facts, the crucial insights from all this material,

13
00:00:39.000 --> 00:00:41.679
<v Speaker 2>so you'll walk away feeling well informed about Ruby's core

14
00:00:41.759 --> 00:00:44.640
<v Speaker 2>ideas and how it's used without getting totally bogged down

15
00:00:44.679 --> 00:00:47.600
<v Speaker 2>in every single detail. Think of it as your express lane.

16
00:00:47.640 --> 00:00:49.920
<v Speaker 1>Absolutely, and for us this is really about the well

17
00:00:49.920 --> 00:00:54.200
<v Speaker 1>there's joy of discovery understanding how Ruby actually empowers developers.

18
00:00:54.359 --> 00:00:56.439
<v Speaker 1>It's a language that's known for letting you focus on

19
00:00:56.479 --> 00:01:00.520
<v Speaker 1>solutions right, whether that's tiny scripts or huge revenue generator services.

20
00:01:00.520 --> 00:01:05.680
<v Speaker 1>It's got a fascinating design philosophy. Okay, so let's unpack that.

21
00:01:06.079 --> 00:01:09.920
<v Speaker 1>The source Hammer's home that Ruby is fundamentally object oriented,

22
00:01:10.239 --> 00:01:12.480
<v Speaker 1>but like, what does that really mean in Ruby? Why

23
00:01:12.599 --> 00:01:13.560
<v Speaker 1>is that so central?

24
00:01:13.599 --> 00:01:17.200
<v Speaker 2>Well, what's really fascinating is how Ruby takes this everything

25
00:01:17.280 --> 00:01:20.680
<v Speaker 2>is an object idea really seriously. It's not just class

26
00:01:20.719 --> 00:01:23.599
<v Speaker 2>as you define yourself. Even things like numbers or strings

27
00:01:23.680 --> 00:01:26.120
<v Speaker 2>or true and false. They're all first class objects.

28
00:01:26.200 --> 00:01:27.599
<v Speaker 1>Everything, even a number.

29
00:01:27.719 --> 00:01:30.439
<v Speaker 2>Yeah. Everything. You can call methods on literally anything. And

30
00:01:30.519 --> 00:01:34.439
<v Speaker 2>for a developer, the insight is this consistency massively simplifies

31
00:01:34.439 --> 00:01:37.519
<v Speaker 2>your mental model. You don't have this split between primitive

32
00:01:37.560 --> 00:01:41.200
<v Speaker 2>types and objects. It's just one universe objects, combined data,

33
00:01:41.280 --> 00:01:44.000
<v Speaker 2>and the logic to work on that data. So like

34
00:01:44.079 --> 00:01:47.280
<v Speaker 2>song dot new Ruby Tuesday that creates an object, a

35
00:01:47.319 --> 00:01:49.840
<v Speaker 2>distinct thing that knows its title, maybe has a method

36
00:01:49.879 --> 00:01:50.560
<v Speaker 2>to play itself.

37
00:01:50.680 --> 00:01:55.000
<v Speaker 1>That consistency does sound incredibly powerful. So if every single

38
00:01:55.040 --> 00:01:58.120
<v Speaker 1>thing is an object and they're all distinct, how does

39
00:01:58.200 --> 00:02:01.560
<v Speaker 1>Ruby keep track? How do they mean their own identity

40
00:02:01.560 --> 00:02:02.040
<v Speaker 1>in state?

41
00:02:02.359 --> 00:02:05.079
<v Speaker 2>Right? So every object gets a unique identity you can

42
00:02:05.079 --> 00:02:08.639
<v Speaker 2>actually see it with the objected method, and beyond that identity,

43
00:02:08.719 --> 00:02:13.360
<v Speaker 2>objects hold their own specific data using instance variables. These

44
00:02:13.360 --> 00:02:15.759
<v Speaker 2>start with an AT symbol. So for like a book

45
00:02:15.800 --> 00:02:18.800
<v Speaker 2>in stock object, you might have at esbn and at price.

46
00:02:19.280 --> 00:02:21.960
<v Speaker 2>That data belongs only to that specific book instance.

47
00:02:22.039 --> 00:02:25.240
<v Speaker 1>Ah okay, So that's the encapsulation idea, bundling the data

48
00:02:25.280 --> 00:02:26.960
<v Speaker 1>and the behavior together exactly.

49
00:02:27.120 --> 00:02:28.680
<v Speaker 2>That's the heart of O women Ruby.

50
00:02:28.879 --> 00:02:31.120
<v Speaker 1>So once you get that core idea, the next question

51
00:02:31.199 --> 00:02:33.800
<v Speaker 1>is obvious, how to actually, you know, get started write

52
00:02:33.840 --> 00:02:37.639
<v Speaker 1>some code our source mentions, version managers like urban Ezy.

53
00:02:38.319 --> 00:02:40.080
<v Speaker 1>Why are they so important for Ruby folks?

54
00:02:40.319 --> 00:02:43.840
<v Speaker 2>Oh? They're hugely beneficial, almost essential, I'd say. The big

55
00:02:43.879 --> 00:02:46.039
<v Speaker 2>win is that they let you install and easily switch

56
00:02:46.120 --> 00:02:49.000
<v Speaker 2>between different Ruby versions on your machine without them interfering

57
00:02:49.039 --> 00:02:51.080
<v Speaker 2>with each other. You might have an old project needing

58
00:02:51.159 --> 00:02:53.919
<v Speaker 2>Ruby two point seven a new one using three point two.

59
00:02:54.599 --> 00:02:58.639
<v Speaker 2>A version manager just handles that smoothly right avoids conflicts exactly.

60
00:02:59.039 --> 00:03:02.280
<v Speaker 2>And the nice thing about Robin a V specifically is

61
00:03:02.280 --> 00:03:04.840
<v Speaker 2>it usually works entirely in your home directory, so you

62
00:03:04.879 --> 00:03:07.520
<v Speaker 2>often don't need pseudo or admin rights to install or

63
00:03:07.560 --> 00:03:10.159
<v Speaker 2>manage Ruby versions make setup much easier.

64
00:03:10.360 --> 00:03:13.159
<v Speaker 1>That is convenient, especially if you're on a shared machine

65
00:03:13.240 --> 00:03:15.599
<v Speaker 1>or just don't want to mess with system wide stuff. Yeah.

66
00:03:15.639 --> 00:03:18.879
<v Speaker 1>And for Windows users, the book points out using WSL,

67
00:03:19.080 --> 00:03:22.360
<v Speaker 1>the Windows subsystem for Linux basically run Linux tools right

68
00:03:22.400 --> 00:03:23.199
<v Speaker 1>there on Windows.

69
00:03:23.439 --> 00:03:26.039
<v Speaker 2>Yeah, WSL is a great optional Windows. Once you've got

70
00:03:26.080 --> 00:03:28.800
<v Speaker 2>Ruby installed one way or another, running a program is

71
00:03:28.840 --> 00:03:32.639
<v Speaker 2>super simple. Ruby values expressiveness. You just make a text file,

72
00:03:32.680 --> 00:03:35.960
<v Speaker 2>maybe call it myprog dot RB. Inside you could just

73
00:03:36.000 --> 00:03:39.240
<v Speaker 2>put puts hello Ruby programmer. Yeah, and maybe puts it

74
00:03:39.319 --> 00:03:41.240
<v Speaker 2>is now hashtag time dot now.

75
00:03:41.319 --> 00:03:43.520
<v Speaker 1>Okay, puts just prints things out yep.

76
00:03:43.360 --> 00:03:45.000
<v Speaker 2>Prince to the console. Then you just go to your

77
00:03:45.039 --> 00:03:48.599
<v Speaker 2>terminal and type Ruby myprog dot rb dot don and

78
00:03:48.680 --> 00:03:51.479
<v Speaker 2>notice that hattag about it a bit. That's Ruby's way

79
00:03:51.479 --> 00:03:53.960
<v Speaker 2>of embedding an expression like time dot now right inside

80
00:03:53.960 --> 00:03:56.520
<v Speaker 2>a strength. It's called interpolation. Super handy.

81
00:03:56.599 --> 00:03:59.199
<v Speaker 1>Okay, so we've got objects for everything and we can

82
00:03:59.280 --> 00:04:02.560
<v Speaker 1>run simple scrap. What about the basic building blocks for

83
00:04:02.599 --> 00:04:05.560
<v Speaker 1>storing data, variables, collections, that sort of thing.

84
00:04:05.879 --> 00:04:09.879
<v Speaker 2>Ruby's pretty clear with its variable conventions, which helps readability.

85
00:04:10.439 --> 00:04:13.520
<v Speaker 2>Regular local variables they start with a lowercase letter or

86
00:04:13.520 --> 00:04:17.279
<v Speaker 2>an underscore. We mentioned instance variables start with at M.

87
00:04:17.480 --> 00:04:21.240
<v Speaker 2>There are also class variables with at M and constants

88
00:04:21.439 --> 00:04:23.800
<v Speaker 2>which start with an upper case letter. Usually class or

89
00:04:23.839 --> 00:04:27.319
<v Speaker 2>module names. Oh, and global variables start with dellar. But

90
00:04:27.399 --> 00:04:30.720
<v Speaker 2>honestly you see globals and class variables used pretty sparingly

91
00:04:30.800 --> 00:04:33.360
<v Speaker 2>in good Ruby code. They can make things harder to

92
00:04:33.439 --> 00:04:34.360
<v Speaker 2>track in large.

93
00:04:34.160 --> 00:04:38.319
<v Speaker 1>Systems, right, potential for confusion there and for organizing collections

94
00:04:38.319 --> 00:04:40.720
<v Speaker 1>of data. Arrays and hashes are the main tools.

95
00:04:40.800 --> 00:04:44.600
<v Speaker 2>Yeah, absolutely, they're the war courses. Arrays are your ordered lists,

96
00:04:44.720 --> 00:04:47.959
<v Speaker 2>indexed by number starting from zero like in many languages.

97
00:04:48.439 --> 00:04:51.319
<v Speaker 2>Hashes are key value stores like dictionaries or maps. In

98
00:04:51.360 --> 00:04:55.480
<v Speaker 2>other languages you index them with arbitrary keys. Very often

99
00:04:55.519 --> 00:04:59.160
<v Speaker 2>you use symbols or strings, and they're flexible, incredibly flexible.

100
00:04:59.319 --> 00:05:02.040
<v Speaker 2>Both a ras and hashes can hold objects of different

101
00:05:02.040 --> 00:05:05.120
<v Speaker 2>types and they grow automatically as you add things. You

102
00:05:05.160 --> 00:05:07.560
<v Speaker 2>can use a raise like stacks with push and pop,

103
00:05:08.079 --> 00:05:10.839
<v Speaker 2>or like queues using shift and push. And for hashes,

104
00:05:10.879 --> 00:05:14.279
<v Speaker 2>the syntax is nice. You can use like key value.

105
00:05:14.399 --> 00:05:17.319
<v Speaker 2>But there's a common shortcut for symbol keys name dot

106
00:05:17.439 --> 00:05:18.879
<v Speaker 2>value just looks cleaner.

107
00:05:19.000 --> 00:05:20.439
<v Speaker 1>Ah, the colon syntax.

108
00:05:20.480 --> 00:05:23.120
<v Speaker 2>I've seen that, Yeah, it's very common, but it's important

109
00:05:23.120 --> 00:05:25.680
<v Speaker 2>to remember that a symbol key like cello is totally

110
00:05:25.720 --> 00:05:28.480
<v Speaker 2>different from a string key like cello. They won't clash,

111
00:05:28.600 --> 00:05:29.879
<v Speaker 2>but they are distinct.

112
00:05:29.600 --> 00:05:32.680
<v Speaker 1>Keys, good distinction. Okay, what about strings? They seem pretty

113
00:05:32.680 --> 00:05:33.480
<v Speaker 1>fundamental too.

114
00:05:33.560 --> 00:05:37.120
<v Speaker 2>They are, and Ruby gives you options single quotes for

115
00:05:37.160 --> 00:05:40.040
<v Speaker 2>simple strings. Double quotes are more powerful. They understand escape

116
00:05:40.040 --> 00:05:43.319
<v Speaker 2>sequences like and for a new line, and crucially, double

117
00:05:43.399 --> 00:05:47.199
<v Speaker 2>quoted strings do that hashtag expression interpolation we saw earlier.

118
00:05:47.439 --> 00:05:49.600
<v Speaker 2>Lets you build strings dynamically, right, and.

119
00:05:49.560 --> 00:05:52.680
<v Speaker 1>I remember reading about here documents for longer text.

120
00:05:53.079 --> 00:05:57.639
<v Speaker 2>Yes, here documents are great for multi line strings you

121
00:05:57.680 --> 00:05:59.920
<v Speaker 2>start with followed by a marker like end off string,

122
00:06:00.560 --> 00:06:03.480
<v Speaker 2>then your lines of text, and finally the marker again

123
00:06:03.560 --> 00:06:06.920
<v Speaker 2>on its own line. There are variations too, like bass

124
00:06:06.959 --> 00:06:10.000
<v Speaker 2>lets you indent the end marker and strips leading white

125
00:06:10.000 --> 00:06:13.319
<v Speaker 2>space from the whole block, which is fantastic for code readability.

126
00:06:13.399 --> 00:06:16.720
<v Speaker 1>That sounds really useful for embedding code snippets or text blocks.

127
00:06:16.720 --> 00:06:20.279
<v Speaker 2>Neatly, it really is. And while we're talking basics method

128
00:06:20.279 --> 00:06:23.480
<v Speaker 2>definitions with death, a key thing in Ruby is that

129
00:06:23.519 --> 00:06:26.800
<v Speaker 2>methods implicitly return the value of the last expression evaluated.

130
00:06:27.279 --> 00:06:29.959
<v Speaker 2>You often don't need an explicit return statement, which leads

131
00:06:29.959 --> 00:06:31.040
<v Speaker 2>to more concise.

132
00:06:30.680 --> 00:06:33.040
<v Speaker 1>Code, fewer keystrokes, less clutter, I like it.

133
00:06:33.199 --> 00:06:37.439
<v Speaker 2>Yeah, And methods can handle arguments flexibly too. Using splats

134
00:06:37.879 --> 00:06:41.360
<v Speaker 2>gathers extra positional arguments into an array, gathers extra keyword

135
00:06:41.439 --> 00:06:43.959
<v Speaker 2>arguments into a hash, and lets you capture a past

136
00:06:44.079 --> 00:06:44.439
<v Speaker 2>end block.

137
00:06:44.600 --> 00:06:47.600
<v Speaker 1>Okay, you mentioned blocks. This is where things get really interesting, right.

138
00:06:47.759 --> 00:06:51.800
<v Speaker 1>The source really emphasizes blocks as a unique, powerful Ruby feature.

139
00:06:52.079 --> 00:06:52.959
<v Speaker 1>What's the deal with them?

140
00:06:53.199 --> 00:06:56.639
<v Speaker 2>They really are special. Think of a block as like

141
00:06:56.759 --> 00:06:59.079
<v Speaker 2>an anonymous chunk of code, a mini method without a

142
00:06:59.160 --> 00:07:03.160
<v Speaker 2>name attached to a method call inside the method that

143
00:07:03.199 --> 00:07:06.480
<v Speaker 2>receives the block. You use the yield keyword to actually

144
00:07:06.519 --> 00:07:08.720
<v Speaker 2>execute that block's code.

145
00:07:08.399 --> 00:07:10.560
<v Speaker 1>So the method calls the block exactly.

146
00:07:10.759 --> 00:07:14.040
<v Speaker 2>The method can yield once or multiple times, maybe passing

147
00:07:14.120 --> 00:07:16.800
<v Speaker 2>different arguments to the block each time it yields. It's

148
00:07:16.839 --> 00:07:19.360
<v Speaker 2>a fundamental way to abstract control structures.

149
00:07:19.439 --> 00:07:21.560
<v Speaker 1>Can you see this pattern a lot for things like

150
00:07:21.600 --> 00:07:24.600
<v Speaker 1>resource management? Right? Like opening a file precisely.

151
00:07:24.920 --> 00:07:27.920
<v Speaker 2>That file dot open example is classic Ruby. You call

152
00:07:28.000 --> 00:07:30.160
<v Speaker 2>file dot open with a file name and pass a block.

153
00:07:30.560 --> 00:07:33.399
<v Speaker 2>The method opens the file yields the open file object

154
00:07:33.439 --> 00:07:35.120
<v Speaker 2>to your block, so you can read or write to it.

155
00:07:35.399 --> 00:07:38.360
<v Speaker 2>And here's the magic. Ruby guarantees that the file gets

156
00:07:38.399 --> 00:07:41.160
<v Speaker 2>closed automatically when the block finishes, even if an error

157
00:07:41.199 --> 00:07:42.800
<v Speaker 2>happens inside the block.

158
00:07:43.279 --> 00:07:46.199
<v Speaker 1>So no manual close needed, less chance of weeks. That's clever,

159
00:07:46.680 --> 00:07:47.199
<v Speaker 1>it really is.

160
00:07:47.240 --> 00:07:51.279
<v Speaker 2>It shifts responsibility. And the truly deep insight about blocks

161
00:07:51.920 --> 00:07:54.920
<v Speaker 2>is that they are closures. This means they capture the

162
00:07:54.959 --> 00:07:58.160
<v Speaker 2>local variables from the environment where they were defined. They

163
00:07:58.240 --> 00:08:01.160
<v Speaker 2>remember that context even after the original scope is gone.

164
00:08:01.279 --> 00:08:02.639
<v Speaker 1>It remember things like.

165
00:08:02.839 --> 00:08:05.360
<v Speaker 2>Yeah, like if you define a block inside a method,

166
00:08:05.800 --> 00:08:09.000
<v Speaker 2>it can still access that method's local variables even when

167
00:08:09.040 --> 00:08:11.360
<v Speaker 2>you pass the block somewhere else to be executed later.

168
00:08:11.839 --> 00:08:15.079
<v Speaker 2>This makes them amazing for things like callbacks. You can

169
00:08:15.120 --> 00:08:17.000
<v Speaker 2>also store a block in a variable as a proc

170
00:08:17.079 --> 00:08:19.959
<v Speaker 2>object and pass it around just like any other object.

171
00:08:20.399 --> 00:08:25.439
<v Speaker 1>Wow, okay, closures. That sounds incredibly flexible. And the source

172
00:08:25.480 --> 00:08:28.879
<v Speaker 1>also mentioned numerator something about making iteration explicit.

173
00:08:29.120 --> 00:08:31.360
<v Speaker 2>Right. Sometimes you have a method that normally takes a

174
00:08:31.360 --> 00:08:33.679
<v Speaker 2>block to iterate, like each char in a string. If

175
00:08:33.679 --> 00:08:35.960
<v Speaker 2>you call it without a block, Ruby often gives you

176
00:08:36.000 --> 00:08:40.039
<v Speaker 2>back an enumertor object instead. This object basically represents the

177
00:08:40.080 --> 00:08:43.279
<v Speaker 2>iteration itself. You can then control it manually, grab the

178
00:08:43.279 --> 00:08:46.240
<v Speaker 2>next element, rewind it, chant it with other enumerators. It

179
00:08:46.320 --> 00:08:48.000
<v Speaker 2>lets you decouple the iteration logic.

180
00:08:48.240 --> 00:08:52.000
<v Speaker 1>Interesting, so more control when you need it. Okay, let's

181
00:08:52.039 --> 00:08:55.720
<v Speaker 1>zoom out a bit. How do Ruby developers organize code?

182
00:08:55.840 --> 00:08:59.919
<v Speaker 1>As projects get bigger, we're talking classes module.

183
00:09:00.320 --> 00:09:03.120
<v Speaker 2>Yeah, this gets into higher level design. So you define

184
00:09:03.120 --> 00:09:06.440
<v Speaker 2>blueprints for objects using class our book in stock example,

185
00:09:06.480 --> 00:09:09.559
<v Speaker 2>earlier is a class. Instances of that class have their

186
00:09:09.600 --> 00:09:12.600
<v Speaker 2>own state like it is bn at price. Ruby gives

187
00:09:12.600 --> 00:09:16.720
<v Speaker 2>you nice shortcuts for defining accessor methods for these instance variables.

188
00:09:17.120 --> 00:09:19.720
<v Speaker 2>At reader creates a getter method, ad writer creates a setter,

189
00:09:19.879 --> 00:09:22.799
<v Speaker 2>and at accessor creates both. Saves a lot of boilerplate.

190
00:09:22.960 --> 00:09:25.240
<v Speaker 1>Right, Those Atrey methods are everywhere in Ruby code.

191
00:09:25.320 --> 00:09:28.559
<v Speaker 2>They are, and then there's access control. By default, methods

192
00:09:28.600 --> 00:09:31.480
<v Speaker 2>are public, anyone can call them. You can declare methods protected,

193
00:09:31.559 --> 00:09:34.120
<v Speaker 2>meaning only the class itself and at subclasses can call

194
00:09:34.120 --> 00:09:36.919
<v Speaker 2>them on an instance of the same family or private,

195
00:09:37.080 --> 00:09:40.240
<v Speaker 2>which is stricter. Private methods can only be called implicitly

196
00:09:40.360 --> 00:09:44.039
<v Speaker 2>without an explicit object receiver, usually means their helper methods

197
00:09:44.080 --> 00:09:45.480
<v Speaker 2>called only from within the same object.

198
00:09:45.799 --> 00:09:51.200
<v Speaker 1>Okay, public protected, private, standard OO concepts. So putting this

199
00:09:51.279 --> 00:09:54.279
<v Speaker 1>together for architecture, there seems to be a big choice.

200
00:09:54.600 --> 00:09:58.639
<v Speaker 1>Use inheritance or use modules sometimes called mixings.

201
00:09:58.720 --> 00:10:02.360
<v Speaker 2>That's a really critical design decision. In Ruby, inheritance, using

202
00:10:02.399 --> 00:10:06.279
<v Speaker 2>class dog mammal represents and is a relationship. A dog

203
00:10:06.360 --> 00:10:09.240
<v Speaker 2>is a mammal, that's its primary identity. But often you

204
00:10:09.320 --> 00:10:13.720
<v Speaker 2>have objects that need certain capabilities, but that capability isn't

205
00:10:13.759 --> 00:10:16.279
<v Speaker 2>their core identity. It's more of a hasa or uses

206
00:10:16.320 --> 00:10:17.080
<v Speaker 2>a relationship.

207
00:10:17.120 --> 00:10:19.600
<v Speaker 1>Well like a person object might need the ability to

208
00:10:19.600 --> 00:10:22.120
<v Speaker 1>be saved to a database, but it uses a database connection,

209
00:10:22.159 --> 00:10:24.200
<v Speaker 1>it doesn't is a database connection exactly.

210
00:10:24.240 --> 00:10:26.559
<v Speaker 2>That's where modules and mixings come in. You define a

211
00:10:26.559 --> 00:10:29.000
<v Speaker 2>set of related methods inside a module, then in your

212
00:10:29.000 --> 00:10:32.279
<v Speaker 2>class you include that module. Ruby effectively mixes in the

213
00:10:32.320 --> 00:10:35.840
<v Speaker 2>module's methods into the class. Think of standard modules like comparable.

214
00:10:35.919 --> 00:10:38.399
<v Speaker 2>If you include comparable and define the comparison method, your

215
00:10:38.440 --> 00:10:42.559
<v Speaker 2>objects automatically get mech and between methods for free or innumerable.

216
00:10:42.759 --> 00:10:45.000
<v Speaker 2>Include that define in each method that yields elements, and

217
00:10:45.039 --> 00:10:47.600
<v Speaker 2>you get map, select, reject, sort, and tons of other

218
00:10:47.639 --> 00:10:48.440
<v Speaker 2>collection methods.

219
00:10:48.600 --> 00:10:52.840
<v Speaker 1>So mixin's are for adding bundles of functionality, promoting flexibility

220
00:10:53.000 --> 00:10:54.679
<v Speaker 1>over rigid inheritance trees.

221
00:10:54.799 --> 00:10:59.559
<v Speaker 2>Precisely it's a cornerstone of idiomatic Ruby design. It favors

222
00:10:59.600 --> 00:11:02.240
<v Speaker 2>compass over inheritance in many cases.

223
00:11:01.960 --> 00:11:04.519
<v Speaker 1>And when you call a method, Ruby has specific rules

224
00:11:04.559 --> 00:11:07.120
<v Speaker 1>for where it looks right the method look up path

225
00:11:07.320 --> 00:11:07.639
<v Speaker 1>it does.

226
00:11:07.679 --> 00:11:09.960
<v Speaker 2>It's important to understand when you call a method on

227
00:11:10.000 --> 00:11:13.039
<v Speaker 2>an object, Ruby first looks in the object's own class.

228
00:11:13.440 --> 00:11:16.360
<v Speaker 2>If it's not found there, it looks in modules that

229
00:11:16.399 --> 00:11:19.399
<v Speaker 2>were included into that class in reverse order of inclusion.

230
00:11:19.720 --> 00:11:21.519
<v Speaker 2>If it's still not found, it goes up to the

231
00:11:21.519 --> 00:11:24.720
<v Speaker 2>superclass and or piece of process. Check the superclass, then

232
00:11:24.720 --> 00:11:27.399
<v Speaker 2>it's included modules that it's superclass, and so on, all

233
00:11:27.440 --> 00:11:28.159
<v Speaker 2>the way up the chain.

234
00:11:28.240 --> 00:11:31.200
<v Speaker 1>Okay, that order makes sense. Class first, then mixin's, then

235
00:11:31.279 --> 00:11:31.919
<v Speaker 1>parent class.

236
00:11:32.000 --> 00:11:35.639
<v Speaker 2>Yep. Knowing that helps you understand overriding and how mixins interact.

237
00:11:35.279 --> 00:11:38.799
<v Speaker 1>With the marivans right shifting gears. Now to the practical side,

238
00:11:38.919 --> 00:11:41.519
<v Speaker 1>the tools developers use day to day. How do you

239
00:11:41.600 --> 00:11:43.879
<v Speaker 1>manage external code libraries?

240
00:11:44.279 --> 00:11:47.559
<v Speaker 2>The Ruby world revolves around Ruby gems. These are packages

241
00:11:47.559 --> 00:11:51.279
<v Speaker 2>of reusable code libraries or applications. The central place to

242
00:11:51.279 --> 00:11:54.559
<v Speaker 2>find them is RubyGems dot org. And to manage these

243
00:11:54.639 --> 00:11:58.840
<v Speaker 2>gems within your specific project, the indispensable tool is bundler.

244
00:11:59.000 --> 00:12:00.759
<v Speaker 1>Bundler and the gem file exactly.

245
00:12:01.200 --> 00:12:03.559
<v Speaker 2>You create a file named gem file in your project rout.

246
00:12:03.879 --> 00:12:07.120
<v Speaker 2>Inside you declare your dependencies. You list the source usually

247
00:12:07.159 --> 00:12:09.840
<v Speaker 2>RubyGems dot org, the Ruby version you're using, and then

248
00:12:09.840 --> 00:12:12.879
<v Speaker 2>each gem your project needs. You can specify versions too,

249
00:12:13.000 --> 00:12:16.120
<v Speaker 2>often using the operator like gemrels seven point zero That

250
00:12:16.159 --> 00:12:19.080
<v Speaker 2>means allow updates within the seven point zero point x series,

251
00:12:19.080 --> 00:12:21.679
<v Speaker 2>but not seven point one or higher. It prevents breaking

252
00:12:21.759 --> 00:12:23.159
<v Speaker 2>changes while allowing patches.

253
00:12:23.399 --> 00:12:26.519
<v Speaker 1>That operator the twittle waka is super common for managing

254
00:12:26.519 --> 00:12:30.519
<v Speaker 1>dependencies safely. What about just running Ruby from the command line.

255
00:12:30.559 --> 00:12:31.720
<v Speaker 1>Any useful tricks there?

256
00:12:31.879 --> 00:12:34.159
<v Speaker 2>Oh yeah, the Ruby command itself has some neat flags.

257
00:12:34.519 --> 00:12:37.600
<v Speaker 2>Takiuls you execute a short snippet of Ruby code directly

258
00:12:37.639 --> 00:12:40.879
<v Speaker 2>from the command line like rubyu puts high. Great for

259
00:12:40.960 --> 00:12:43.879
<v Speaker 2>quick tests. Daki key is cool for processing input. It

260
00:12:43.919 --> 00:12:46.360
<v Speaker 2>wraps your code in a loop that reads input line

261
00:12:46.360 --> 00:12:48.679
<v Speaker 2>by line, a secutes your code, and prints the result.

262
00:12:49.159 --> 00:12:51.840
<v Speaker 2>Often used with the variable which holds the current line

263
00:12:52.039 --> 00:12:54.120
<v Speaker 2>and I always recommend using deck w It turns on

264
00:12:54.200 --> 00:12:57.919
<v Speaker 2>warning messages which can kept subtle issues or deprecated usage.

265
00:12:58.039 --> 00:13:00.559
<v Speaker 1>Good tip. What about scripts that need to read from

266
00:13:00.559 --> 00:13:02.440
<v Speaker 1>files given on the command line for.

267
00:13:02.480 --> 00:13:06.360
<v Speaker 2>That, Ruby provides ARGF. It's this magic object that acts

268
00:13:06.399 --> 00:13:09.840
<v Speaker 2>like a single stream combining standard input and any files

269
00:13:09.879 --> 00:13:12.840
<v Speaker 2>listed on the command line. Makes writing Unix style filter

270
00:13:12.919 --> 00:13:16.240
<v Speaker 2>scripts really easy. And don't forget EENV. It's a hash

271
00:13:16.399 --> 00:13:18.440
<v Speaker 2>like object that gives you access to all the system's

272
00:13:18.519 --> 00:13:20.799
<v Speaker 2>environment variables. Crutical for configuration.

273
00:13:21.000 --> 00:13:24.960
<v Speaker 1>Okay, useful command line foo. Now for exploring and testing interactively,

274
00:13:25.080 --> 00:13:26.559
<v Speaker 1>ORB seems like the standard tool.

275
00:13:26.759 --> 00:13:31.240
<v Speaker 2>HERB interactive Ruby is absolutely essentful. It's a r epl

276
00:13:31.600 --> 00:13:34.519
<v Speaker 2>read evil print loop. You type, Ruby code executes it

277
00:13:34.559 --> 00:13:37.559
<v Speaker 2>immediately and shows you the result. So fantastic for trying

278
00:13:37.600 --> 00:13:41.240
<v Speaker 2>out ideas, exploring how objects work, testing a library, or

279
00:13:41.320 --> 00:13:44.600
<v Speaker 2>even debugging small things as built in help. It's configurable.

280
00:13:44.960 --> 00:13:47.840
<v Speaker 1>Yeah, every Rubius uses HERB constantly.

281
00:13:47.480 --> 00:13:50.960
<v Speaker 2>Your personal Ruby playground pretty much, But what about when

282
00:13:51.000 --> 00:13:54.039
<v Speaker 2>things go wrong in a bigger way debugging? We all

283
00:13:54.080 --> 00:13:56.440
<v Speaker 2>start with put statements, right, punting things out?

284
00:13:56.600 --> 00:13:59.759
<v Speaker 1>Huh Yeah? Puts Debugging is a time honored tradition, and

285
00:13:59.759 --> 00:14:02.480
<v Speaker 1>PE is often better than puts because it calls the

286
00:14:02.519 --> 00:14:05.960
<v Speaker 1>inspect method, giving you a more detailed representation of an object.

287
00:14:06.120 --> 00:14:09.159
<v Speaker 1>PP pretty prints complex objects, making them easier to read.

288
00:14:09.399 --> 00:14:11.600
<v Speaker 1>But when you need more power, Ruby ships with an

289
00:14:11.600 --> 00:14:13.679
<v Speaker 1>official debugger debug dot rb.

290
00:14:14.000 --> 00:14:17.000
<v Speaker 2>Okay, a real debugger. What can it do? Standard debugger stuff?

291
00:14:17.200 --> 00:14:20.480
<v Speaker 2>You can set break points break to pause execution at

292
00:14:20.519 --> 00:14:23.480
<v Speaker 2>specific lines or methods. Then you can step through the

293
00:14:23.480 --> 00:14:26.440
<v Speaker 2>code line by line using step which goes into method calls,

294
00:14:26.519 --> 00:14:30.159
<v Speaker 2>or next, which steps over them. You can expect variable values,

295
00:14:30.440 --> 00:14:34.279
<v Speaker 2>execute arbitrary code in the current context, continue execution until

296
00:14:34.279 --> 00:14:38.120
<v Speaker 2>the next breakpoint. It's powerful for tracing complex logic.

297
00:14:38.399 --> 00:14:40.840
<v Speaker 1>Sounds like GDB or PDB for Ruby.

298
00:14:41.039 --> 00:14:44.200
<v Speaker 2>Very similar concept. Yes, there's also a very popular third

299
00:14:44.240 --> 00:14:47.720
<v Speaker 2>party gem called pri A. Lot of developers prefer Pride

300
00:14:47.759 --> 00:14:50.759
<v Speaker 2>because it feels more like an enhanced HERBS session right

301
00:14:50.799 --> 00:14:55.000
<v Speaker 2>inside your paused application. It has great features like syntax highlighting,

302
00:14:55.279 --> 00:14:58.759
<v Speaker 2>showing method source code with show source, navigating the call stack,

303
00:14:58.799 --> 00:15:01.360
<v Speaker 2>and even interacting with the shell. It really blurs the

304
00:15:01.399 --> 00:15:03.159
<v Speaker 2>line between debugging and exploration.

305
00:15:03.320 --> 00:15:05.759
<v Speaker 1>Priy. I've heard good things about that one. Okay, let's

306
00:15:05.759 --> 00:15:09.399
<v Speaker 1>talk types. Ruby is famously dynamically typed flexible, but sometimes

307
00:15:09.480 --> 00:15:12.320
<v Speaker 1>errors pop up late. The source mentions typed Ruby though,

308
00:15:12.360 --> 00:15:13.080
<v Speaker 1>what's that about?

309
00:15:13.440 --> 00:15:16.879
<v Speaker 2>Right? So Ruby is dynamically typed meaning type checks happen

310
00:15:16.919 --> 00:15:19.840
<v Speaker 2>at runtime, not before method calls are looked up when

311
00:15:19.840 --> 00:15:23.600
<v Speaker 2>they're actually called. That's late binding. This gives Ruby immense flexibility,

312
00:15:23.679 --> 00:15:26.960
<v Speaker 2>especially for metaprogramming. It's also strongly typed, which is good.

313
00:15:27.080 --> 00:15:29.159
<v Speaker 2>It won't silently convert a string to a number. If

314
00:15:29.200 --> 00:15:31.159
<v Speaker 2>you try to add them mi, it'll raise a type error.

315
00:15:31.320 --> 00:15:32.840
<v Speaker 2>Helps prevent certain kinds of bugs.

316
00:15:33.240 --> 00:15:37.919
<v Speaker 1>Okay, dynamic, but strong, So what's typed? Ruby? Adding static types?

317
00:15:38.240 --> 00:15:42.159
<v Speaker 2>Kind of? It's about adding optional, gradual static type checking

318
00:15:42.399 --> 00:15:45.120
<v Speaker 2>to get some of the benefits like catching type errors

319
00:15:45.120 --> 00:15:48.919
<v Speaker 2>before you run the code, better editor support like autocompletion,

320
00:15:49.480 --> 00:15:53.279
<v Speaker 2>and improved refactoring confidence without losing all of Ruby's dynamic power.

321
00:15:54.000 --> 00:15:57.120
<v Speaker 2>The official approach introduced in Ruby three is RBS Ruby

322
00:15:57.159 --> 00:16:01.039
<v Speaker 2>Signature language. You write type definitions and separate dot RBS files.

323
00:16:01.080 --> 00:16:03.799
<v Speaker 1>Separate files not in the Ruby code itself.

324
00:16:03.600 --> 00:16:06.320
<v Speaker 2>Mostly yes in don RB's files. You define the types

325
00:16:06.360 --> 00:16:10.759
<v Speaker 2>of constants, variables, method arguments, return values, instance variables, et cetera.

326
00:16:11.120 --> 00:16:14.320
<v Speaker 2>You use syntax like string to mean a string or

327
00:16:14.399 --> 00:16:17.799
<v Speaker 2>nil a nillable type. You declare types for atch reader

328
00:16:17.879 --> 00:16:21.440
<v Speaker 2>atch writer. You write full method signatures. Then tools can

329
00:16:21.480 --> 00:16:24.519
<v Speaker 2>check your Ruby code against these RBS signatures. There's also

330
00:16:24.840 --> 00:16:28.120
<v Speaker 2>type prof, another tool that tries to infer RBS signatures

331
00:16:28.120 --> 00:16:30.360
<v Speaker 2>from your existing untyped Ruby code.

332
00:16:30.519 --> 00:16:33.600
<v Speaker 1>Interesting, so it's an add on layer for type safety.

333
00:16:33.320 --> 00:16:36.639
<v Speaker 2>Exactly, and it's still evolving. Another popular system developed its

334
00:16:36.679 --> 00:16:40.080
<v Speaker 2>tripe is sorbet, which often uses type annotations written as

335
00:16:40.120 --> 00:16:44.000
<v Speaker 2>comments inside the Ruby files. Different approach, similar goals.

336
00:16:43.879 --> 00:16:47.360
<v Speaker 1>Right, Okay. Now for something that sounds really advanced metaprogramming,

337
00:16:47.679 --> 00:16:50.519
<v Speaker 1>the source calls it Ruby's deeper magic. What are we

338
00:16:50.519 --> 00:16:51.200
<v Speaker 1>talking about here?

339
00:16:51.399 --> 00:16:55.679
<v Speaker 2>Huh? It does feel like magic. Sometimes. Meta programming is

340
00:16:55.799 --> 00:16:58.879
<v Speaker 2>essentially writing code that operates on other code or even

341
00:16:58.879 --> 00:17:02.759
<v Speaker 2>itself at run time. Ruby makes this unusually accessible because

342
00:17:02.759 --> 00:17:06.640
<v Speaker 2>of its object model. Key concepts include reflection, the ability

343
00:17:06.680 --> 00:17:09.279
<v Speaker 2>of a program to examine its own structure. You can

344
00:17:09.319 --> 00:17:12.440
<v Speaker 2>ask an object what instance variables it has? Instance variables,

345
00:17:12.759 --> 00:17:15.960
<v Speaker 2>what methods it responds to? Methods find all objects of

346
00:17:15.960 --> 00:17:19.079
<v Speaker 2>a certain class objects based on each object.

347
00:17:18.720 --> 00:17:20.920
<v Speaker 1>So the code can look at itself, yes.

348
00:17:21.000 --> 00:17:24.279
<v Speaker 2>And modify itself too. For instance, Ruby has singleton methods

349
00:17:24.319 --> 00:17:27.759
<v Speaker 2>methods defined on a single specific object instance rather than

350
00:17:27.759 --> 00:17:30.839
<v Speaker 2>its class. And here's a key insight. What we call

351
00:17:30.880 --> 00:17:33.920
<v Speaker 2>class methods in Ruby, they're actually just singleton methods defined

352
00:17:33.960 --> 00:17:35.119
<v Speaker 2>on the class object itself.

353
00:17:35.160 --> 00:17:37.200
<v Speaker 1>WHOA Okay, that bends my brain a little.

354
00:17:37.319 --> 00:17:39.359
<v Speaker 2>It's a nie consequence of the object model. You can

355
00:17:39.359 --> 00:17:42.960
<v Speaker 2>also dynamically define new methods using defined method This is

356
00:17:43.039 --> 00:17:47.599
<v Speaker 2>super powerful for reducing boilerplate or creating dsl's domain specific languages.

357
00:17:48.119 --> 00:17:51.039
<v Speaker 2>And then there's the ultimate power tool, method missing. It's

358
00:17:51.039 --> 00:17:53.359
<v Speaker 2>a special method that gets called whenever you try to

359
00:17:53.400 --> 00:17:55.359
<v Speaker 2>call a method on an object that doesn't actually.

360
00:17:55.200 --> 00:17:58.440
<v Speaker 1>Exist, so you can catch non existent method calls and

361
00:17:59.279 --> 00:18:00.559
<v Speaker 1>do something else exactly.

362
00:18:00.599 --> 00:18:03.160
<v Speaker 2>You can intercept the call, look at the method name

363
00:18:03.240 --> 00:18:06.279
<v Speaker 2>and arguments, and maybe delegate it somewhere else, or dynamically

364
00:18:06.319 --> 00:18:08.839
<v Speaker 2>define the method on the fly, or interpret it as

365
00:18:08.839 --> 00:18:12.599
<v Speaker 2>part of a DSL. It's the heart of many Ruby libraries,

366
00:18:12.920 --> 00:18:16.680
<v Speaker 2>like active records, dynamic finders, oh when refinements are a

367
00:18:16.720 --> 00:18:20.200
<v Speaker 2>newer feature, they let you temporarily modify or monkey patch

368
00:18:20.279 --> 00:18:23.759
<v Speaker 2>in existing class, but only within a specific lexical scope,

369
00:18:23.839 --> 00:18:26.680
<v Speaker 2>avoiding the global impact of traditional monkey patching.

370
00:18:26.960 --> 00:18:31.519
<v Speaker 1>Metaprogramming sounds incredibly powerful, but maybe something to use carefully.

371
00:18:31.200 --> 00:18:35.039
<v Speaker 2>Very carefully. It can make code incredibly concise, expressive, but

372
00:18:35.200 --> 00:18:38.240
<v Speaker 2>also harder to understand and debug if overused.

373
00:18:38.480 --> 00:18:41.640
<v Speaker 1>Got it okay? Connecting this to the bigger picture, concurrency

374
00:18:42.119 --> 00:18:44.799
<v Speaker 1>making programs do multiple things at once. Why is this

375
00:18:44.839 --> 00:18:46.839
<v Speaker 1>so important now? And how does Ruby handle it?

376
00:18:47.119 --> 00:18:51.079
<v Speaker 2>Concurrency is vital for responsiveness, especially in web applications, and

377
00:18:51.119 --> 00:18:55.039
<v Speaker 2>for taking advantage of modern multi core processors. Ruby offers

378
00:18:55.039 --> 00:18:58.519
<v Speaker 2>a few different models. The traditional approach is using threads.

379
00:18:58.759 --> 00:19:00.880
<v Speaker 2>These are OS level threads. You create them with thread

380
00:19:00.880 --> 00:19:04.359
<v Speaker 2>dot new. They run seemingly in parallel. You often need

381
00:19:04.400 --> 00:19:08.200
<v Speaker 2>synchronization tools like thread mutex to safely manage access to

382
00:19:08.240 --> 00:19:11.720
<v Speaker 2>share data between threads, preventing race conditions, and you use

383
00:19:11.839 --> 00:19:13.279
<v Speaker 2>join to wait for a thread to.

384
00:19:13.240 --> 00:19:15.680
<v Speaker 1>Finish standard threading model. What else?

385
00:19:15.839 --> 00:19:18.680
<v Speaker 2>Then you have fibers. These are quite different. They provide

386
00:19:18.720 --> 00:19:22.920
<v Speaker 2>cooperative multitasking, sometimes called core routines. With fibers, control is

387
00:19:22.960 --> 00:19:26.880
<v Speaker 2>transferred explicitly. One fiber runs until it explicitly yields control,

388
00:19:27.079 --> 00:19:30.000
<v Speaker 2>allowing another fiber to run. You decide when the switch happens,

389
00:19:30.359 --> 00:19:33.440
<v Speaker 2>not the OS scheduler. This gives you very fine grain control,

390
00:19:33.480 --> 00:19:37.400
<v Speaker 2>but doesn't automatically leverage multiple CPU cores for parallel execution.

391
00:19:37.960 --> 00:19:41.799
<v Speaker 1>Okay, Threads for OS level parallelism with caveats and older

392
00:19:41.880 --> 00:19:45.920
<v Speaker 1>Ruby versions, fibers for explicit cooperative switching, and then the

393
00:19:45.960 --> 00:19:48.720
<v Speaker 1>source mentions. Ractors new in Ruby three.

394
00:19:48.960 --> 00:19:52.200
<v Speaker 2>Ractors are the big new thing for true parallelism in Ruby.

395
00:19:52.680 --> 00:19:55.599
<v Speaker 2>They were introduced specifically to get around the limitations of

396
00:19:55.640 --> 00:19:59.799
<v Speaker 2>the old Global Interpreter lock GIL that prevented parallel x

397
00:20:00.000 --> 00:20:03.559
<v Speaker 2>acution of Ruby code and threads. The key idea behind

398
00:20:03.640 --> 00:20:07.680
<v Speaker 2>ractors is a shared nothing architecture. Each ractor is like

399
00:20:07.680 --> 00:20:10.359
<v Speaker 2>an isolated actor or process running in.

400
00:20:10.319 --> 00:20:13.599
<v Speaker 1>Parallel shared nothing, so they don't share memory like threads.

401
00:20:13.920 --> 00:20:18.759
<v Speaker 2>Mostly no, They communicate by passing messages, specifically copies of

402
00:20:18.799 --> 00:20:22.839
<v Speaker 2>shareable objects back and forth using methods like send, take yield,

403
00:20:22.920 --> 00:20:27.440
<v Speaker 2>and receive. Objects that are deeply immutable like numbers, symbols, true, false,

404
00:20:27.440 --> 00:20:30.640
<v Speaker 2>frozen strings in a rays can be shared directly. Most

405
00:20:30.680 --> 00:20:33.319
<v Speaker 2>other objects are unsharable and get copied or moved when

406
00:20:33.359 --> 00:20:37.359
<v Speaker 2>sent between ractors. The strict isolation model makes parallel programming

407
00:20:37.480 --> 00:20:40.680
<v Speaker 2>much safer, as it drastically reduces the potential for tricky

408
00:20:40.720 --> 00:20:44.359
<v Speaker 2>concurrency bugs caused by multiple threads modifying the same data simultaneously.

409
00:20:44.480 --> 00:20:48.200
<v Speaker 1>So raptors are Ruby's answer for safe multi core parallelism.

410
00:20:48.359 --> 00:20:50.960
<v Speaker 2>Interesting. Finally, let's touch on the web. Ruby is huge

411
00:20:50.960 --> 00:20:54.319
<v Speaker 2>in web development, obviously, what are the key pieces there? Absolutely,

412
00:20:54.920 --> 00:20:57.440
<v Speaker 2>Ruby made a massive impact on the web historically you

413
00:20:57.480 --> 00:21:00.440
<v Speaker 2>at things like CGI scripts and ERB is a core

414
00:21:00.440 --> 00:21:03.720
<v Speaker 2>templating language. It embeds Ruby code within text files off

415
00:21:03.759 --> 00:21:08.319
<v Speaker 2>in HTML using percent tags. But a crucial development was rack.

416
00:21:09.000 --> 00:21:12.640
<v Speaker 2>RAC provides a standard minimal interface between web servers like

417
00:21:12.720 --> 00:21:16.480
<v Speaker 2>Puma or Unicorn and Ruby. Web applications or frameworks. Think

418
00:21:16.519 --> 00:21:18.160
<v Speaker 2>of it as a universal adapter.

419
00:21:18.039 --> 00:21:21.119
<v Speaker 1>So Rack allows different frameworks and servers to talk to each.

420
00:21:20.960 --> 00:21:24.319
<v Speaker 2>Other exactly a promotes modularity. You can build applications as

421
00:21:24.359 --> 00:21:27.839
<v Speaker 2>a stack of RAC compatible components or middleware. On top

422
00:21:27.880 --> 00:21:30.279
<v Speaker 2>of Rack, you have frameworks. Sinatra is a well known

423
00:21:30.359 --> 00:21:34.359
<v Speaker 2>lightweight framework great for smaller applications or APIs. It provides

424
00:21:34.400 --> 00:21:37.000
<v Speaker 2>a simple way to define routes and actions. And of

425
00:21:37.039 --> 00:21:39.559
<v Speaker 2>course there's Rails, the giant framework built on Ruby. Though

426
00:21:39.559 --> 00:21:41.960
<v Speaker 2>we're focusing on the language itself today and looking ahead,

427
00:21:42.000 --> 00:21:44.960
<v Speaker 2>there's even experimentation with Ruby dot mOsm compiling Ruby to

428
00:21:44.960 --> 00:21:47.759
<v Speaker 2>web assembly to run directly in web browsers. That's pretty wild.

429
00:21:48.000 --> 00:21:52.119
<v Speaker 1>Ruby in the browser. Fascinating. Wow. What a comprehensive tour.

430
00:21:52.759 --> 00:21:56.119
<v Speaker 1>We've gone from Ruby's core everything is an object's philosophy

431
00:21:56.119 --> 00:22:00.799
<v Speaker 1>and getting set up through the fundamental building blocks like variables, collections, strings.

432
00:22:01.240 --> 00:22:03.759
<v Speaker 1>Then we dove into those really unique Ruby features like

433
00:22:03.799 --> 00:22:08.240
<v Speaker 1>blocks and closures, wrestled with design choices like inheritance versus mixin's,

434
00:22:08.519 --> 00:22:11.440
<v Speaker 1>looked at the essential tools like gems, Bundler, herb. We

435
00:22:11.519 --> 00:22:15.319
<v Speaker 1>covered debugging, the move towards typed Ruby with RBS, the

436
00:22:15.359 --> 00:22:18.880
<v Speaker 1>mind bending power of metaprogramming, and the different flavors of

437
00:22:18.920 --> 00:22:22.640
<v Speaker 1>concurrency with threads, fibers and now ractors. And finally it's

438
00:22:22.759 --> 00:22:25.799
<v Speaker 1>roll on the web. This deep dive has really given us,

439
00:22:25.799 --> 00:22:28.720
<v Speaker 1>and hopefully you, a solid grasp of Ruby three point two.

440
00:22:28.880 --> 00:22:30.960
<v Speaker 2>Yeah, and this brings us to a key point for you,

441
00:22:31.039 --> 00:22:34.000
<v Speaker 2>the listener. You've basically just gotten a shortcut to understanding

442
00:22:34.039 --> 00:22:37.559
<v Speaker 2>Ruby's capabilities, its strengths, It's design philosophy. You're now equipped

443
00:22:37.559 --> 00:22:39.880
<v Speaker 2>to understand not just how to use certain features, but

444
00:22:39.920 --> 00:22:42.319
<v Speaker 2>why they exist and why Ruby is designed the way

445
00:22:42.319 --> 00:22:45.759
<v Speaker 2>it is. From that consistent OO foundation to things like

446
00:22:45.839 --> 00:22:47.599
<v Speaker 2>raptors for modern parallelism.

447
00:22:47.880 --> 00:22:51.000
<v Speaker 1>Indeed, and maybe the enduring a peal of Ruby What

448
00:22:51.039 --> 00:22:53.759
<v Speaker 1>the source really highlights is how it lets developers focus

449
00:22:53.759 --> 00:22:56.519
<v Speaker 1>on solving problems, often with code that feels expressive and

450
00:22:56.640 --> 00:23:00.559
<v Speaker 1>well intuitive. So, with this versatile language now better understood,

451
00:23:00.559 --> 00:23:03.680
<v Speaker 1>the provocative thought is what problem, or maybe what curiosity

452
00:23:03.720 --> 00:23:05.400
<v Speaker 1>will you explore next using Ruby
