How does the standard library allow you to coerce a String into an Integer with Integer('1') #=> 1? Is there a language feature that allows one to create this kind of conversion syntax in a class?
It's not a class, just a method in disguise.
We can do this -
'1'.to_i => 1
Related
I'm a new user of Ruby. As far I can see it is very easy to change a variables(object) class
#create an object
n=1
n.class
=> Fixnum
n="Abc"
n.class
=> String
Is it a way to secure a data type of the variable? For example like in Java, when the variable is an integer it cannot take other values than integers.
Thank you!
You can't.
In Ruby, you can only operate on objects, but variables aren't objects, so there is no way to ask a variable about its type.
Also, there is no concept of "type" in Ruby.
I'll use python as an example of what I'm looking for (you can think of it as pseudocode if you don't know Python):
>>> a = 1
>>> type(a)
<type 'int'>
I know in ruby I can do :
1.9.3p194 :002 > 1.class
=> Fixnum
But is this the proper way to determine the type of the object?
The proper way to determine the "type" of an object, which is a wobbly term in the Ruby world, is to call object.class.
Since classes can inherit from other classes, if you want to determine if an object is "of a particular type" you might call object.is_a?(ClassName) to see if object is of type ClassName or derived from it.
Normally type checking is not done in Ruby, but instead objects are assessed based on their ability to respond to particular methods, commonly called "Duck typing". In other words, if it responds to the methods you want, there's no reason to be particular about the type.
For example, object.is_a?(String) is too rigid since another class might implement methods that convert it into a string, or make it behave identically to how String behaves. object.respond_to?(:to_s) would be a better way to test that the object in question does what you want.
you could also try: instance_of?
p 1.instance_of? Fixnum #=> True
p "1".instance_of? String #=> True
p [1,2].instance_of? Array #=> True
Oftentimes in Ruby, you don't actually care what the object's class is, per se, you just care that it responds to a certain method. This is known as Duck Typing and you'll see it in all sorts of Ruby codebases.
So in many (if not most) cases, its best to use Duck Typing using #respond_to?(method):
object.respond_to?(:to_i)
I would say "yes".
Matz had said something like this in one of his talks,
"Ruby objects have no types."
Not all of it but the part that he is trying to get across to us.
Why would anyone have said
"Everything is an Object" then?
To add he said "Data has Types not objects".
RubyConf 2016 - Opening Keynote by Yukihiro 'Matz' Matsumoto
But Ruby doesn't care as much about the type of object as the class.
We use classes, not types. All data, then, has a class.
12345.class
'my string'.class
Classes may also have ancestors
Object.ancestors
They also have meta classes but I'll save you the details on that.
Once you know the class then you'll be able to lookup what methods you may use for it. That's where the "data type" is needed.
If you really want to get into details the look up...
"The Ruby Object Model"
This is the term used for how Ruby handles objects. It's all internal so you don't really see much of this but it's nice to know. But that's another topic.
Yes! The class is the data type. Objects have classes and data has types. So if you know about data bases then you know there are only a finite set of types.
text blocks
numbers
variable_name.class
Here variable name is "a"
a.class
every variable have a prop with name class. if you print it, it will tell you what type it is. so do like this:
puts a.class
I have a specific class C and I would like to overload some math operators.
I already overloaded +, i, *, and / so that I can do things like
a = C.new
b = C.new
a + b
a + 2
a + 2.0
To treat the last three cases, I am systematically testing for the type of the operand: is it C, Fixnum or Float, other possibilities are rejected. My first question is: is it the right way to do that?
Next I also want to be able to do
2.0 + A
How should I do it? Should I provide a conversion of some sort? Can these two problems be solved by the same method?
I believe the answer to "ruby operator overloading question" addresses both your points by using is_a? and coerce.
With regards to your first point. The normal approach in Ruby is to use respond_to? where possible, rather than checking for type. If for some reason you specifically need to check for type, then using is_a? is the correct way.
I am wanting to clarify if it is not possible to declare types in Ruby or is it just not necessary? If someone wanted to declare datatypes would it be possible.
Update: My point in asking is to understand if providing a static type for variables that won't change type will provide a performance increase, in theory.
Some languages as C or Java use “strong” or “static” variable typing. Ruby is a “dynamically typed” language aka "duck typing", which means that variable dynamically changes its own type when type of assigned data has changed.
So, you can't declare variable to some strict type, it will always be dynamic.
What are you trying to do?
You can create your own class:
class Boat
end
If you want an easy way to make a class for holding data, use a struct:
class Boat < Struct.new(:name, :speed)
end
b = Boat.new "Martha", 31
You can NOT declare the class of a variable or method argument, like you can in C. Instead, you can check the type at run time:
b.is_a?(Boat) # Includes subclasses of Boat
b.class == Boat
One proposal to add typing to Ruby is http://bugs.ruby-lang.org/issues/5583 by Yasushi Ando (of parse.y famtour fame). My favorite comment was:
(b) not sure how it can honor duck typing. i think the whole idea is
to (optionally) roast the duck!
If I correctly understood what you mean with type, each Class in Ruby defines a type.
1.class
# => Fixnum
You can create a class to define a custom type
class Book
end
b = Book.new
b.class
# => Book
Or does this method just indicate a unique integer that each object has?
It is a combination of many parameters, value, object type, place in memory.
More can be read here
It isn't a direct reference to the memory location and the "encoding" is specific to a particular Ruby implementation. If you can read C code, you may find it instructive to look at the rb_obj_id and id2ref methods in gc.c in the Ruby 1.8.6 source. You can also read more about the "encoding" in the "Objects embedded in VALUE" section of the partial translation of the Ruby Hacking Guide chapter 2.
It's worth noting that you can perform a reverse-lookup of object IDs using:
ObjectSpace._id2ref(object_id)
For example:
ObjectSpace._id2ref(0) #=> false
ObjectSpace._id2ref(1) #=> 0
ObjectSpace._id2ref(2) #=> true
ObjectSpace._id2ref(3) #=> 1
ObjectSpace._id2ref(4) #=> nil
well, it depends on what you mean by "ruby" ;) In jruby it's just a unique integer as far as I can tell.
Also, things like numbers aren't the memory location. I forget all the details and am sure someone will give them to you.
irb(main):020:0> 1.object_id
=> 3
irb(main):021:0> (2-1).object_id
=> 3
In "normal" ruby (MRI 1.8.x and 1.9.x) it's just a unique value.
This is also the case in IronRuby