So as I understand it, the === operator tests to see if the RHS object is a member of the LHS object. That makes sense. But how does this work in Ruby? I'm looking at the Ruby docs and I only see === defined in Object, I don't see it in Integer itself. Is it just not documented?
Integer is a class, which (at least in Ruby) means that it is just a boring old normal object like any other object, which just happens to be an instance of the Class class (instead of, say, Object or String or MyWhateverFoo).
Class in turn is a subclass of Module (although arguably it shouldn't be, because it violates the Liskov Substition Principle, but that is a discussion for another forum, and is also a dead horse that has already been beaten many many times). And in Module#=== you will find the definition you are looking for, which Class inherits from Module and instances of Class (like Integer) understand.
Module#=== is basically defined symmetric to Object#kind_of?, it returns true if its argument is an instance of itself. So, 3 is an instance of Integer, therefore Integer === 3 returns true, just as 3.kind_of?(Integer) would.
So as I understand it, the === operator tests to see if the RHS object is a member of the LHS object.
Not necessarily. === is a method, just like any other method. It does whatever I want it to do. And in some cases the "is member of" analogy breaks down. In this case it is already pretty hard to swallow. If you are a hardcore type theory freak, then viewing a type as a set and instances of that type as members of a set is totally natural. And of course for Array and Hash the definition of "member" is also obvious.
But what about Regexp? Again, if you are formal languages buff and know your Chomsky backwards, then interpreting a Regexp as an infinite set of words and Strings as members of that set feels completely natural, but if not, then it sounds kind of weird.
So far, I have failed to come up with a concise description of precisely what === means. In fact, I haven't even come up with a good name for it. It is usually called the triple equals operator, threequals operator or case equality operator, but I strongly dislike those names, because it has absolutely nothing to do with equality.
So, what does it do? The best I have come up with is: imagine you are making a table, and one of the column headers is Integer. Would it make sense to write 3 in that column? If one of the column headers is /ab*a/, would it make sense to write 'abbbba' in that column?
Based on that definition, it could be called the subsumption operator, but that's even worse than the other examples ...
It's defined on Module, which Class is a subclass of, which Integer is an instance of.
In other words, when you run Integer === 3, you're calling '===' (with the parameter 3) on the object referred to to by the constant Integer, which is an instance of the class named Class. Since Class is a subclass of Module and doesn't define its own ===, you get the implementation of === defined on Module.
See the API docs for Module for more information.
Umm, Integer is a subclass of Object.
Related
I'm analyzing a block of code written in ruby.
I don't know the language and I need to understand an operation.
def restore
m = ObjectName.where(prop: User.where(email: 'admin#email.com').first.element_id).last
m.todo!
m.waiting!
...
end
what "m.todo!" and "m.waiting!" are doing?
I cannot understand if it is assigning a "true" value or a value that is the opposite of the current one like: m.todo = !m.todo
Thank you very much
! and ? are valid parts of a method name in Ruby. They don't have any special meaning, though ! is conventionally used for mutative or destructive actions, and ? is conventionally used for predicate methods.
In this example, there are two methods named todo! and waiting! being called - nothing fancier. If I had to guess, those are methods which simply perform a combined "update a state variable and save" operation (hence, mutative).
In Ruby, foo.bar is the syntax for a message send. It will first evaluate the expression foo (which is either dereferencing a local variable or a receiverless message send to the implicit receiver self) and then send the message bar to the resulting object.
Once you know what message send in Ruby looks like, it is easy to see what m.todo! does: It will first evaluate the expression m (which is either dereferencing a local variable or a receiverless message send to the implicit receiver self) and then send the message todo! to the resulting object.
Method names ending in ! are typically used to mark the "more surprising" of a pair of methods. So, if you have two Methods, both of which do similar things, then the one with the bang at the end is the "more surprising" one. A good example are Process::exit and Process::exit!. Both exit the currently running Ruby process, but the "normal" version (i.e. the one without the bang) runs the exit handlers normally, whereas the "surprising" Version exits immediately without running the exit handlers.
Note: there seems to be a lot of misunderstanding About the naming convention for bang methods. So, let me be clear:
Bang methods have absolutely nothing to do with mutation or destruction. It is simply about surprise. See the Process::exit! example above which has nothing to do with mutation.
Bang methods are always paired with a non-bang method. They mark the "more surprising" variant of a pair of methods. If there is no pair of methods, there is no bang. See, for example Array#collect!, which does have a bang because it is the more surprising variant of Array#collect, since it mutates its receiver; however, Array#append does not have a bang even though it also mutates its receiver because there is no corresponding "less surprising" method.
what "m.todo!" and "m.waiting!" are doing? I cannot understand if it is assigning a "true" value or a value that is the opposite of the current one like: m.todo = !m.todo
They do whatever the author of those methods wants. You will have to look that up in the documentation. Those are not methods of the Ruby core or standard library.
We have do-and-replace functions like map!, reject!, reverse!, rotate!. Also we have binary operations in short form like +=, -=.
Do we have something for mathematical round? We need to use a = a.round, and it's a bit weird for me to repeat the variable name. Do you know how to shorten it?
OK, smart guys have already explained, why there is no syntactic sugar for Float#round. Just out of curiosity I’m gonna show, how you might implement this sugar yourself [partially]. Since Float class has no ~# method defined, and you do rounding quite often, you might monkeypatch Float class:
class Float
def ~#
self.round # self is redundant, left just for clarity
end
end
or, in this simple case, just (credits to #sawa):
alias_method :~#, :round
and now:
~5.2
#⇒ 5
a = 2.45 && ~a
#⇒ 2
Since Numerics are immutable, it’s still impossible to modify it inplace, but the above might save you four keyboard hits per rounding.
As for destructive methods, it is impossible since numerals are immutable, and it would not make sense. Would you want a numeral 5.2 that behaves as 5?
As for syntax sugar, it would be a mess if every single method had one. So there isn't. And since syntax sugar is defined in the core level, you cannot do anything in an ordinary Ruby script to create a new one.
Ruby's numeric types are immutable: they are value objects. Therefore you won't find any methods that mutate a number in place.
Because the numeric types are immutable, certain optimizations are possible that would not be possible with mutable numbers. In c-ruby, for example, a reference, which may point to any kind of object, is normally a pointer to an object. But if the reference is to a Fixnum, then the reference contains the integer itself, rather than pointing to an instance of Fixnum. Ruby does a number of magic tricks to hide this optimization, making it appear that an integer really is an instance of a Fixnum.
To make numbers mutable would make this optimization impossible, so I don't expect that Ruby will ever have mutable numeric types.
For example, I've checked the documentation on certain methods, like sort. And it looks like the only difference between .sort and .sort! is that one sorts self in place and the other returns an array. I'm a little unclear on what that means - they seem to effectively do the same thing.
Can anyone help me understand this a little better?
When to Use Bang Methods
Technically, the exclamation point (or bang) doesn't intrinsically mean anything. It's simply an allowable character in the method name. In practice, however, so-called bang methods generally:
Changed objects in-place. For example, #sort! sorts self in place, while #sort returns a new array created by sorting self.
Some bang methods return nil if no changes were made, which can cause problems with method chains. For example:
'foo'.sub 'x', 'y'
# => "foo"
'foo'.sub! 'x', 'y'
#=> nil
Use bang methods when you want to mark a method as creating notable side effects, producing destructive operations, or otherwise requiring additional caution or attention. This is largely by convention, though, and you could make all your methods bang methods if you were so inclined.
Methods with a bang(!) are meant to signify a little more caution is required. So, either modification in place vs. not in place (if you are modifying the object in place - you better be sure that you really want to), or in other cases like find_by and find_by! (see here) where one causes an exception if no record is found and one doesn't cause an exception.
Can you guess which one does and which one does not cause an exception?
The methods with the exclamation point alter the actual object they're called on, where as the methods without will just return a new object that has been manipulated.
i.e.
pizza = 'pepperoni'
pizza.capitalize
Now the pizza variable will still equal 'pepperoni'.
If we then call
pizza.capitalize!
The pizza variable will now equal 'Pepperoni'
"Inches/yard: #{12*3}"
"#{"Tora! "*3}"
The second example is confusing, unless you remember that everything is an object in
Ruby (yes, even string literals! They are of class String.). Since the string literal
creates a String object, you can act on it just like any other object. In this case,
multiplying a string by 3 simply does what you would think: makes three copies of the
string.
I read the above para in one of the ruby book. The first line says The second example is confusing, unless you remember that everything is an object in Ruby. What is there in the second example that i should remember ,everything is an object in ruby ? Isn't it just a feature that multiplying by 3 will print tora three times ?
I don't exactly understand what does the author want me to understand from the above paragraph
Well, yes you can consider it a feature maybe, but what the author is perhaps trying to explain (although not very clearly at least in this one paragraph), is that what actually is happening is this:
"Tora !" is an object of class String ("everything is an object")
"you can act on it just like any other object", meaning:
"you can call any method on it just like any other object".
In this case you are calling the method * (multiply).
So what ACTUALLY is happening is that the "Tora !" String gets called in a fashion like this:
"Tora ! ".*(3)
=> "Tora ! Tora ! Tora ! "
You see? The operator * is just a method on the String object.
In many simpler languages operators are actually "baked into" the language itself, and do not operate on the targets as method calls.
If you're not used to other languages you might not find it all that remarkable, since in Ruby it's just a normal everyday thing. You just never need to type 1.+(2), Ruby does it for you automatically when you type 1 + 2.
So this is what the author wants you to remember - all operators and operations are just essentially method calls on other objects.
"Tora! a" is an instance of the String class. You can call methods on it. This isn't possible in many languages, e.g. PHP.
('*' is just the method name)
"#{"Tora! "*3}"
"Isn't it just a feature that multiplying by 3 will print tora three times ?".
That is inexact. There is no such thing as a multiplying operator in Ruby. There is a method ".*" (and the parser treats "*" the same way) defined on both String and Numeric objects (but both don't print anything). They do very different things, but the result is what you'd expect.
Well, maybe this was not what the author wanted you to understand, it is important anyway.
I have just started using Ruby and I am reading "Programming Ruby 1.9 - The Pragmatic Programmer's Guide". I came across something called symbols, but as a PHP developer I don't understand what they do and what they are good for.
Can anyone help me out with this?
It's useful to think of symbols in terms of "the thing called." In other words, :banana is referring to "the thing called banana." They're used extensively in Ruby, mostly as Hash (associative array) keys.
They really are similar to strings, but behind the scenes, very different. One key difference is that only one of a particular symbol exists in memory. So if you refer to :banana 10 times in your code, only one instance of :banana is created and they all refer to that one. This also implies they're immutable.
Symbols are similar to string literals in the sense that share the same memory space, but it is important to remark they are not string equivalents.
In Ruby, when you type "this" and "this" you're using two different memory locations; by using symbols you'll use only one name during the program execution. So if you type :this in several places in your program, you'll be using only one.
From Symbol doc:
Symbol objects represent names and some strings inside the Ruby interpreter. They are generated using the :name and :"string" literals syntax, and by the various to_sym methods. The same Symbol object will be created for a given name or string for the duration of a program‘s execution, regardless of the context or meaning of that name. Thus if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.
So, you basically use it where you want to treat a string as a constant.
For instance, it is very common to use it with the attr_accessor method, to define getter/setter for an attribute.
class Person
attr_accessor :name
end
p = Person.new
p.name= "Oscar"
But this would do the same:
class DontDoThis
attr_accessor( "name" )
end
ddt = DontDoThis.new
ddt.name= "Dont do it"
Think of a Symbol as a either:
A method name that you plan to use later
A constant / enumeration that you want to store and compare against
For example:
s = "FooBar"
length = s.send(:length)
>>> 6
#AboutRuby has a good answer, using the terms "the thing called".
:banana is referring to "the thing
called banana."
He notes that you can refer to :banana many times in the code and its the same object-- even in different scopes or off in some weird library. :banana is the thing called banana, whatever that might mean when you use it.
They are used as
keys to arrays, so you look up :banana you only have one entry. In most languages if these are Strings you run the risk of having multiple Strings in memory with the text "banana" and not having the code detect they are the same
method/proc names. Most people are familiar with how C distinguishes a method from its call with parentheses: my_method vs. my_method(). In Ruby, since parentheses are optional, these both indicate a call to that method. The symbol, however, is convenient to use as a standin for methods (even though there really is no relationship between a symbol and a method).
enums (and other constants). Since they don't change they exhibit many of the properties of these features from other languages.