Ruby: Is Variable Is Object in Ruby

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



Leave a reply



Submit