Resolve to Keep Learning (scope resolution operator)


#1

https://www.codecademy.com/courses/learn-ruby/lessons/object-oriented-programming-ii/exercises/resolve-to-keep-learning?action=lesson_resume

I am confused about the purpose of the scope resolution operator. The lesson states that this concept of namespacing is "how Ruby doesn’t confuse Math::PI and Circle::PI"

But why can’t you just call the PI constant as Math.PI and Ruby not be “confused”? Obvioulsy you’re calling it on the Math module, not the Circle module since you specify Math as the receiver, correct? What am I missing here?


#2
puts Math.PI
undefined method `PI` for Math:Module

#3

But that’s my question. WHY does it require a special operator to work as opposed to JavaScript libraries, whose constants and methods can be called in the “normal” fashion (e.g. Math.PI or Math.random() etc.). The lesson portrays the reason as having to do with Ruby needing to differentiate between the Math and Circle modules that contain the same constant name, but I don’t see what that has to do with it since you’re specifying the module name already. The only purpose I can see is that it shows you’re calling a constant or method on a module instead of a class, but that’s not the reason the lesson gave.


#4

Modules do not have attributes, only constants and methods written into the namespace. We cannot invoke instances like we can with a class. In JavaScript (pre 2009) there were no classes, only constructor functions, and now that there are classes, they behave in very similar fashion, still but have an internal constructor. Classes permit instance.method and instance.attribute because the implementation of the class may involve instances.

Math is not a class, but a module, so it has no attributes or instance methods. The methods that are tied to the module are not in the same scope as the rest of the program, hence the scope resolution, Math::PI.


#5

Sorry, “attributes” was a typo. I’m still not getting the reason the scope resolution operator is needed beyond, “this is just the way it is in Ruby.” The lesson explanation:

See that double colon we just used? That’s called the scope resolution operator, which is a fancy way of saying it tells Ruby where you’re looking for a specific bit of code. If we say Math::PI, Ruby knows to look inside the Math module to get that PI, not any other PI (such as the one we created in Circle).

doesn’t make sense to me. Why would Math::PI be any more specific than Math.PI dot notation (if that were allowable syntax in Ruby), since both specify the Math module. Why would it look for the PI constant anywhere else other than where you specified in the first place? THAT is what I’m totally not getting.

Oh well, I’m just going to keep going through the lessons, and hopefully some point down the road it will make sense.


#6

Math::PI is more specific than PI
The . operator can’t be used for constants - why that is/what the reasoning is, I don’t know. (I don’t know much ruby) And it’s rather difficult to google as well, it’s either really subtle or people really really like to avoid the question. I’m sure the answer is there for someone who has a good grasp of the language - which I don’t have at all


#7

implies that Math is a Class, which it is not. It is just a collection of methods and constants that can only be called from that scope, hence, Math::PI.

class Maths

    def pi
        Math::PI
    end
end

calc = Maths.new()
puts calc.pi
3.141592653589793

#8

How so?

module Stuff
  def self.pi
    3.14
  end
end

class Things
  PI = 3.14
end

puts Stuff.pi  # is fine, `.` isn't restricted to classes, but it can't be used for constants
puts Things.PI # not valid, despite Things being a class

Things.PI won’t fly because . can’t access constants (what’s it got to do with what Things/Math is?)


#9

Well, that helps clarify things. So this works because we’ve reassigned the constant to a method?

puts Maths.new.pi

#10

Thank you both. That helps me wrap my mind a little bit better around how things are working, no thanks to the lesson narrative :wink:


#11

Not sure why you instantiated Maths but yes, . can be used for accessing methods

As far as python (and js for that matter) goes, we just look up an attribute and if it’s callable then hey that’s great, but that doesn’t change how we look it up, it’s just a value like any other. Ruby? ??? And I can’t really search for it because all the results are blogs written by people who shouldn’t have keyboard access, I bet there are plenty of japanese resources making sense out of all these things and oh look we have this thing called python let’s do that instead.


#12

I spy a @zystvan
What benefit does the :: operator bring to ruby as a language over just using . for everything like python does?

Is it just there to say that you’re not invoking the values? To be explicit about that they are constants, not method calls? Does that mean that :: exists because ruby syntax for calling doesn’t necessarily have a () in the end? Can I consider . a look-up-and-call operator? And :: calls if the name starts with a lower case letter, otherwise is constant-lookup? Not sure I even want to know…


#13

pi is undefined in my earlier code, so cannot be written like,

Maths.pi

but can be accessed as a transient instance…

Maths.new.pi

Here is some more tomfoolery…

class Maths
    def self.PI
      Math::PI
    end
    def pi
        Math::PI
    end
end

calc = Maths.new()
puts calc.pi

puts Maths.new.pi

puts Maths.PI

#14

According to this article, . is the message operator, as opposed to :: being the scope operator.

https://en.wikipedia.org/wiki/Scope_resolution_operator#Ruby

(Don’t mean to step on Zeke’s toes, and hope he will pick up on this topic so we get his insights.)


#15

And the term “message” is completely lost on me.

I suspect it’s got to do with actor model and message passing between objects blah blah smalltalk… but it doesn’t map to anything concrete in my head. And those messages are handled by ruby aren’t they, there’s no switch where you do different actions based on different messages, so why would a ruby coder not just call it method call, where’s the difference there? And :: sometimes does the same thing as .


#16

For that I have no answer, and have to defer to Zeke once he chimes in.


#17

Welp, time to learn me some smalltalk.


#18

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.