I'm having trouble with exercise 39, in particular understanding it. I copied everything correctly and the code seems to work as shown on the website but I can't understand the details of why it's working.

I can't understand how the code itself works, how the indented code is making the functions work the way they are. also I can't get "delete" to work, it gives me an error when I type something like "delete(cities, 'NY')" in the test file. Otherwise it works exactly as the website says.

Also, this is completely unrelated, do you think that it would be a good idea if I was to study discrete mathematics to improve my programming skills?From what I understand this is the math behind how computers work, it's taught in computer sciences courses. I want to take a CS university course in the future.

What are the prerequisites for it? I don't remember anything from high school so I may need to re-learn a bit of high school math first if that's needed.

I can't answer your question on the exercise, but I just want to comment on your question on math in CS.

I don't think you have to worry too much reviewing high school math, typically pre-university math courses are focused on algebra, arithmetic, and trigonometry...and some basic calculus. A lot of core CS math does require basic algebra and arithmetic, but you'll learn the advance math that you need in CS program itself which will focus more on logic, set theory, probability stuff. You'll need trigonometry if you are going to do computer graphics. Again, as long as you still remember the basic, all the advance stuff will be part of your CS program.

Of course it doesn't hurt to review what you'd known...but don't worry too much over them.

@Oleg_the_Russian I don't blame you for getting lost, the tutorial threw a lot of new concepts at you all at once before introducing them gently. I recommend that you keep a note book of all the things that you don't understand or are confused about, move on and do the next 2-3 lessons, then come back and try to answer your own questions.

the tutorial threw a lot of new concepts at you all at once before introducing them gently. I recommend that you keep a note book of all the things that you don't understand or are confused about, move on and do the next 2-3 lessons

I actually did just that, now I'm stuck at a part that introduces classes. I'm trying to write down some of the concepts there in my notebook, it confuses me as much as the part I asked about here.

I was studying ruby hard way. That question is the one I spent longest time to understand. I end up printing the question and asking a senior developer to explain to me. That was the first time I have seen hash concept.

So the issue with this exercise is kinda a part of how the book was written. It is essentially a concept-for-concept rewrite of learn python the hard way, and in python recreating the dictionary before you understand how classes work makes a lot more sense.

If you are interested in the hard way approach, I might suggest retyping (you said copied in your post, but the book strongly relies on the assumption of your fingers being involved) the exercise again, and possibly buying the book so you can gain access to the accompanying videos.

If you would like an explanation of why delete(cities, 'NY') does not work, one can be had below. To make sure this is a voluntary choice it's hidden behind a details tag. This goes in-depth and may (read: almost certainly does) cover things you already know.

HERE THERE BE SPOILERS

The exercise is introducing the dictionary/hash concept by having you rebuild it from scratch. In order to keep you from doing something called 'polluting the top level namespace' it is written in the form of class methods on a Dict class object. Lets define our terms.

method : An isolated unit of code that can be called. you can define methods anywhere, and there are several kinds with strange, overlapping relationships. Unfortunately, a full explanation of all of the types of method is beyond the scope of this answer, but we can cover instance and class methods, and talk briefly about something called scope.

instance method: This is a method that can be called from an instance of an object. Yeah, not very helpful, I know. Let's look at a very small example.

class Cat
def meow
puts "meow"
end
end
kitty = Cat.new
kitty.meow

If you run that code, it will print "meow" to the screen. There's a lot of extra work there, though. Why not just do this:

puts "meow"

There are lots of good answers to that question but the most important in my eyes is that the second example does not make a cat. Even if the only thing the cat we create does is meow, the act of creating a cat object is part of the point of the code. I used that object word again, so let's talk about that word.

The word object, in ruby, is like the word object in english. Any thing that one can give identity to is an object. (This is not true, but it is so close to true that I do not want to explain otherwise) Strings, numbers, methods, procedures, arrays, classes, they're all objects. Every object has a class, which is the type of thing that it is. There can be relationships between classes, which is to say that one can have a class that uses another class to define itself. Deep, I know. One of the most important relationship types is called inheritance, and it's way too much for me to cover at the moment, but it is important to explain the idea of a top level namespace, that thing that we do not want to pollute. Every class a user of ruby defines inherits from a class called Object (unless the user forces it not to). Lets look at another code example

def meow
puts "meow"
end
meow

If you run this code, it will print meow, just like every other example. However, it will not create a cat. So what is doing the meowing?

Object is.

When you define a method, and that method definition is not inside of a class, or another method, or any particular, programmer specified object, it is defined on the class Object.

(It is more accurate to say that whenever you define a method, it is defined in the current self, which is Object, unless you have told ruby to make it be something else. No need to worry about that right now, though.)

So, we now know how instance methods are defined and what they get defined on. Lets talk for a moment about class methods.

class method: a method that is defined on a class rather than instances of that class.

Again, not super useful. Lets meow.

class Cat
def self.meow
puts "meow"
end
end
Cat.meow

Like all the other examples, this prints 'meow'. It creates a Cat class, but we never make a cat object. So what is doing the meowing?

The Cat class is.

I mentioned offhandedly that pretty much everything is an object in ruby. This includes classes. When we define a method using the self.method_name syntax, we are actually doing two things.

We ask ruby for the value of self. Ruby hands us back self's class. The code in my example that does this bit is self.

We take what ruby handed us back and we define a method on that thing, which is in this case the class of self. The code in my example that does this bit is def <...>.meow

Now, where we put self, we can put a class name, too. Time to meow again.

class Cat
def Cat.meow
puts "meow"
end
end
Cat.meow

In fact, if a class is known to ruby, we don't need to be 'in' that class to define methods on it.

class Cat
end
def Cat.meow
puts 'meow'
end
Cat.meow

Neat, eh? This is a result of the strange and wonderful semantics of the def keyword in ruby. It tries very hard to understand what you asked it for and to do the right thing, regardless of where you are in your codebase. Here's some absurd nonsense that I will not explain in depth that demonstrates this trait.

Please never write code like this, but try to understand why it is possible, as this depth of understanding of the ruby interpreter may assist you in later work.

Now, I keep talking about Classes, but the book used a Module. This is part of that python heritage of the Hard Way series. It is significantly more idiomatic (read: culturally acceptable) in python to divide up codebases into modules, whereas in ruby we typically use classes for such separations. This is especially true with regard to making our own data structures. We typically would prefer to define a class for the data structure, define instance methods on the class, and let the individual objects carry around all the code they need to function, rather than constantly reaching out to the module that created them. In python, it is more common to create functions that return a given data structure, and group them into a module. There are several language features in python that make this more comfortable than it is in ruby, like import thing as t.

Modules in ruby have very similar features to classes in ruby. The main difference is called 'instantiation', which is a fancy way to say we can make objects of that type. A module cannot be instantiated; it is a single object that holds all of the code placed in it. (A module can be included into an object, but that's beyond the scope of this answer. It's really cool though, and I'd advise doing some research about it later.) So, aside from the examples that involve the code Cat.new, which instantiates a Cat object, anything I've said about classes applies to modules. Another meowing example.

module Cat
def Cat.meow
puts "meow"
end
end
Cat.meow

So, I've written a lot of darn words without addressing the key points of your question, which were

How does the indented code make the functions work the way that they do?

Why doesn't delete(cities, 'NY') work?

The indented code defines methods on the module Dict. The indentation is there for readability, the mechanism that allows it to work is the idea of module method as explained above. The reason that delete(cities, 'NY') does not work is that the method is defined on the module Dict, rather than in Object. Dict.delete(cities, 'NY') should work.

I hope that helps. Thanks for asking a neat question, I enjoyed the opportunity to solidify my own learning by trying to explain it.

Edit: That explanation got kinda long, sorry! If clarification would be helpful to you, please ask!

Edit 2: Welp, apparently firefox doesn't support the details tag, and out version of discourse doesn't handle [spoiler]. Dang.