Determining type of an object in ruby
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.
Ruby: Is variable is object in ruby?
"In ruby, everything is an object" is basically true.
But more accurately, I would say that any value that can be assigned to a variable or returned from a method is an object. Is a variable an object? Not really. A variable is simply a name of an object (also known as a "pointer") that allows you locate it in memory and do stuff with it.
shajin = Person.new()
In this snippet, we have a variable shajin
, which points to an object (an instance of the person class). The variable is simply the identifier for an object, but is not the object itself.
I think it was a trick question. Ultimately object orientation is feature for humans to understand complex programs, but computers are not object oriented themselves. Drill down enough layers and objects cease to exist in any language.
So perhaps it's more fair to say: "In ruby, everything important is an object".
How do I check if a variable is an instance of a class?
It's almost exactly the same. You can use Object
's instance_of?
method:
"a".instance_of? String # => true
"a".instance_of? Object # => false
Ruby also has the is_a?
and kind_of?
methods (these 2 are aliases, and work exactly the same), which returns true
is one of the superclasses matches:
"a".is_a? String # => true
"a".is_a? Object # => true
How to check there is only one object inside the ruby variable?
Michael's answer should work already, but another option is to check if it includes the Enumerable
module (should support all "Array"-ish objects, unless they have their own custom implementation):
@object.is_a? Enumerable
# => returns true if Array-ish or false
Examples
# Array
[].is_a? Enumerable
# => true
# Hash
{}.is_a? Enumerable
# => true
# Set
[].to_set.is_a? Enumerable
# => true
# Subclass of any of the above
class MyArr < Array
end
MyArr.new.is_a? Enumerable
# => true
# ActiveRecord::Relation
User.all.is_a? Enumerable
# => true
# String
'somestring'.is_a? Enumerable
# => false
# Integer/Float
123.is_a? Enumerable
# => false
(123.45).is_a? Enumerable
# => false
# Time
Time.now.is_a? Enumerable
# => false
Gotcha
## Rails 4:
ActionController::Parameters.new.is_a? Enumerable
# => true
## Rails 5:
ActionController::Parameters.new.is_a? Enumerable
# => false
# in Rails 5, ActionController::Parameters no longer inherits from Hash
# ActionController::Parameters is the type of the variable `params` in your controllers
# Because practically speaking you can loop over it, so it should still be an "Array"
# Therefore, you might want to use the following instead of `.is_a? Enumerable`
@object.respond_to? :each
# => returns true if Array-ish or false
ActionController::Parameters.new.respond_to? :each
# => true
Function to find object type in Ruby
The assumption you've made is that if the value returned by a mathematical operation is an integer, the value's class will be Fixnum. That's not correct.
Take a look:
a = 5
puts a.class
# => Fixnum
b = 5.0
puts b.class
# => Float
Mathematically speaking, 5 and 5.0 are the same number and that number is an integer. But 5 and 5.0 in Ruby (like many other programming languages) are not the same. One is a fixed-point value (ergo Fixnum) and the other is a floating-point value (Float). A Fixnum can represent integers only, but a Float can represent both integers and fractions (but, it behooves me to mention, not all fractions).
In Ruby, when you do a mathematical operation with two Fixnums, a Fixnum is returned:
a = 4
puts a.class # => Fixnum
x = a ** 2
puts x # => 16
puts x.class # => Fixnum
However, if either number is a Float, a Float is returned:
a = 4
x = a ** 2.0
puts x # => 16.0
puts x.class # => Float
b = 4.0
puts b.class # => Float
y = b ** 2
puts y # => 16.0
puts y.class # => Float
y = b ** 2.0
puts y # => 16.0
puts y.class # => Float
You asked how to "find the type of an object," and the answer to that question is to use the Object#class
method, as above. But as you can see, "Is the object a Fixnum?" and "Is the object an integer?" are two different questions.
If you want to know if a number in Ruby is an integer even if it's a Float, refer to the excellent answers to this question: Checking if a Float is equivalent to an integer value in Ruby
Is it possible to determine if a variable is an activerecord object or not?
Object.is_a? to the rescue:
user = User.first
str = "Hello"
user.is_a?(ActiveRecord::Base) # true
str.is_a?(ActiveRecord::Base) # false
ruby: check if two variables are the same instance
According to the source, the Object#equal?
method should do what you're trying to do:
// From object.c
rb_obj_equal(VALUE obj1, VALUE obj2)
{
if (obj1 == obj2) return Qtrue;
return Qfalse;
}
So the ruby code you would write is:
obj1.equal?(obj2)
Ruby: if !object.nil? or if object
There are differences. For example:
false.nil?
# => false
So:
if !false.nil?
'foo'
end
# => "foo"
if false
'foo'
end
# => nil
As @tokland suggested, in most cases using !obj.nil?
construction is unnecessary.
Checking variable type in Ruby
I think you are looking for Object#class
. Here:
element = {}
element.class
# => Hash
a = []
a.class
# => Array
This will make your switch case as follows:
case element
when String
# do something
when Fixnum
# do something
when Hash
# do something
when Array
# do something
end
Note:
As mentioned by @ndn in comments below, case
statement should not have .class
in it (which I had initially in my answer). You can find the explanation here.
Why can you change the value of a local variable in Ruby in a function using another method but not with an assignment operator?
The key here is that you can never change a Ruby object's core self
, once it has been created it will always be the same object until garbage collected and destroyed. It is only possible to alter properties of the object.
You can, however, change variables or object references such as instance variables, constants, attr_accessor
properties among other things.
So in this case:
def uppercase2(value)
value = "WILLIAM"
end
This reassigns the value
local variable. It does nothing to the original object.
If you want to replace that text you need to use methods on the object to effect it, if supported. In this case there is a method:
def uppercase2(value)
value.replace("WILLIAM")
end
These are generally termed in-place modifications as in the object itself is manipulated rather than swapped for another object.
Related Topics
Detecting If This Is an Iframe Load or Direct
Rails Routes: Get Without Param :Id
Run a Command Line with Custom Environment
In Ruby or Rails, Why Is "Include" Sometimes Inside the Class and Sometimes Outside the Class
Rails 3.2 Activeadmin 'Collection Is Not a Paginated Scope.' Error
How to Share State Between Scenarios Using Cucumber
How Does Ruby Allow a Method and a Class with the Same Name
Positive Lookahead Doesn't Stop at First Occurrence
Ruby: What Is the Order of Keys/Values Returned by Hash.Keys and Hash.Values Methods
Ruby on Rails Country/State Select Enigma
Rails:Runtimeerror - Can't Modify Frozen Array When Running Rspec in Rails
Write Array of Radix-2 Numeric Strings to Binary File in Ruby
Get Response Headers from Curb
How to Connect to Browser Using Ruby Selenium Webdriver
How to I Add a Hyperlink to a Cell in Axlsx
How to Split a String into Consecutive Substrings of Length at Most 3 in All Possible Ways