Ruby & Ruby On Rails Interview Preparation- Part 1 (Ruby)

Ruby Devs
Ruby Devs
Sep 5, 2018 · 7 min read
  1. Explain OOPS concepts like encapsulation, inheritance and polymorphism?

Encapsulation means bundling data and methods that work together on data.The internal presentation of the object created is hidden from the outside. Only object defined can work with the internal data. The public methods defined opens up a defined way to access the logic inside an object.

Inheritance is the mechanism of basing an object or class upon another object (prototypical inheritance) or class (class-based inheritance).

Inheritance in Ruby

Polymorphism is the ability to redefine methods for defined classes.

Polymorphism in Ruby

2. What are classes and objects?

Classes are the extensible program or code for creating objects , providing initial values for states and implementations of behaviour. They are blueprints for creating objects.

Object can be a variable, a data structure, a function, or a method, and as such, is a value in memory referenced by an identifier. It is a software bundle of variables and related methods.

3. What is the difference between class and module?

We can think of Module in terms of a library providing methods which we can use across classes. Modules are different then interfaces in Java, as the interfaces in Java are abstract but module defined functions actually has the implementation in them.

Source: Stack Overflow
Difference between class and module in Ruby

4. How would you declare and use a constructor in Ruby?

In most programming languages a new keyword is provided to create an object instance, however ruby is a bit different. It provides a ‘new’ method on the class to create an instance.

For e.g. in Java we have

MyClass myObject= new MyClass();

However, in ruby we can do this using,

myObject = MyClass.new()

Ruby’s constructor has three jobs:

  1. Allocate space
  2. Initialise instance variables
  3. Return the newly create instance

In ruby this is done by the help of ‘initialize’ instance method, but what exactly is happening. In Ruby the class method ‘new’ is defined as:

def self.new(*args)
instance = allocate
instance.send(:initialize, *args)
instance
end

So in ruby we declare it with the help of ‘initialize’ instance method and use it with the help of the ‘new’ class method.

5. How would you create getter and setter methods in Ruby?

In Ruby, we can do this using ‘attr_accessor’ in our class. ‘attr_accessor’ created the getter and setter for the declared variables in Ruby.

6. Difference between class and instance variables in ruby?

Class variables in Ruby are the variables which are declared with ‘@@’ signs before them, these variables are accessible both by the instance and class or subclasses as well.

class Entity

@@instances = 0

def initialize
@@instances += 1
@number = @@instances
end

def who_am_i
"I'm #{@number} of #{@@instances}"
end

def self.total
@@instances
end
end

entities = Array.new(9) { Entity.new }

entities[6].who_am_i # => "I'm 7 of 9"
Entity.total # => 9

Here, the class Entity, has a class variable @@instances, as we can see it is accessible during initialisation, instance method ‘who_am_i’ and class method ‘self.total’.

However, we should be using class instance variables instead.

class Entity

@instances = 0

class << self
attr_accessor :instances # provide class methods for reading/writing
end


def initialize
self.class.instances += 1
@number = self.class.instances
end

def who_am_i
"I'm #{@number} of #{self.class.instances}"
end

def self.total
@instances
end
end

entities = Array.new(9) { Entity.new }

entities[6].who_am_i # => "I'm 7 of 9"
Entity.instances # => 9
Entity.total # => 9

Note that, we have implemented the class variables as class instance variables, here, in the ‘initialize’ method as well as in the class instance methods we are accessing it using the ‘self.class.variable_name’,but what is the benefit. Here are some of the benefits :

  1. The class variable can be accessible throughout the subclass or ancestors might change the value, so there is a risk of reopening and changing the variable values
#Ancestor class object is changing the value of @@var
class Foo

@@var = "foo"

def self.var
@@var
end
end

Foo.var # => "foo" (as expected)

class Object
@@var = "object"
end

Foo.var # => "object" (!)
____________________________________________________________________#Subclasses changing the class variable class Woof

@@sound = "woof"

def self.sound
@@sound
end
end

Woof.sound # => "woof"

class LoudWoof < Woof
@@sound = "WOOF"
end

LoudWoof.sound # => "WOOF"
Woof.sound # => "WOOF" (!)

2. All the problems that come with the ‘global variable’.

3. The main difference is the behaviour concerning inheritance: class variables are shared between a class and all its subclasses, while class instance variables only belong to one specific class.

Instance Variables on a class are the instance variables on that class, not on instance variable on the instance of that class

#Source Stack overflow
Instance variable on a class:
class Parent
@things = []
def self.things
@things
end
def things
self.class.things
end
end

class Child < Parent
@things = []
end

Parent.things << :car
Child.things << :doll
mom = Parent.new
dad = Parent.new

p Parent.things #=> [:car]
p Child.things #=> [:doll]
p mom.things #=> [:car]
p dad.things #=> [:car]

Here , @things is an instance variable of class Parent, where we are declaring a class method ‘self.things’.

Similarly, there can be instance variable on an instance of a class.

#Source Stack overflow
Instance variable on instance of a class:
class Parent
def initialize
@things = []
end
def things
@things
end
def add_things(value)
@things.push(value)
end
end


mom = Parent.new
dad = Parent.new
mom.add_things("jewellery")
dad.add_things("car")
dad.add_things("bike")
dad.things => ["car", "bike"]

7. What are the three levels of method access control for classes and what do they signify?

The three levels are :public, :protected, :private.

class A
def my_public_method
end
private
def my_private_method
end
protected
def my_protected_method
end
end
A.new.my_public_method => nil
A.new.my_private_method => NoMethodError: private method `my_private_method' called for #<A:0x007fbc73914f38>
A.new.my_protected_method => NoMethodError: protected method `my_protected_method' called for #<A:0x007fbc74019e28>

public — The methods declared under public(default) are accessible to everyone, however, initialize method is always private.

private — The methods cannot be called by an explicit receiver, the receiver is always self, which means that private methods can only be invoked in context of current object.

A question for you: Can class methods be private?

protected — The methods can be invoked by the objects of the class and its subclasses only.

More on Protected:

#Source rubylearning.com
class Person
def initialize(age)
@age = age
end
def age
@age
end
def compare_age(c)
if c.age > age
"The other object's age is bigger."
else
"The other object's age is the same or smaller."
end
end
protected :age
end

chris = Person.new(25)
marcos = Person.new(34)
puts chris.compare_age(marcos)
#With age protected rather than private, chris can ask marcos to execute age, because chris and marcos are both instances of the same class. But if you try to call the age method of a Person object when self is anything other than a Person object, the method will fail.

8. What is the meaning of ‘self’ in Ruby?

self in Ruby gives access to the current object, the object receiving the current message.

In the context of class, it is used to create class methods.

9. Explain how (almost) everything is an object in Ruby?

If we are passing arguments to a method, then the argument list is not an object, however, everything in ruby evaluates an object.

Please follow the below link to understand it completely.

10. Explain what singleton methods are. What is Eigenclass in Ruby?

Singelton Methods are the method that can be provided to a single objects. A method given only to a single object is called a singleton method.

class SingletonTest
def non_singleton_method
puts "Not a Singelton method"
end
end
s1 = SingletonTest.newdef s1.singleton_method
puts "Singelton Method"
end
s1.non_singleton_method => "Not a Singelton method"
s1.singleton_method => "Singelton Method"

Eigen Classes or Singelton Classes

class A
def c
class << self #this creates an eigenclass
def b
self
end
end
end
end
class Foo
def self.bar
puts "I'm public"
end
class << self
private
def baz
"I'm private"
end
end
end
Foo.bar # => I'm public
Foo.baz # => NoMethodError: private method `baz' called for
class Foo
def self.bar
p "I'm public"
end
@baz = "I'm a class variable!"class << self
attr_accessor :baz
end
end
Foo.bar
=> "I'm public"
Foo::baz
=>"I'm a class variable!"

11. Describe Ruby method lookup path?

class Aend
A.ancestors => [A, Object, Kernel, BasicObject]
#But we can have a module extended, prepended, or included.
module Include
def call(level)
puts "#{level} include"
super(level + 1) rescue nil
end
end

module Prepend
def call(level)
puts "#{level} prepend"
super(level + 1) rescue nil
end
end

module Extend
def call(level)
puts "#{level} extend"
super(level + 1) rescue nil
end
end

class Super
def call(level)
puts "#{level} super"
super(level + 1) rescue nil
end
end

class Klass < Super
include Include
prepend Prepend


def call(level)
puts "#{level} klass"
super(level + 1) rescue nil
end

end

thing = Klass.new


def thing.call(level)
puts "#{level} singleton"
super(level + 1) rescue nil
end

thing.extend(Extend)


thing.call(1)
=> 1 singleton
2 extend
3 prepend
4 klass
5 include
6 super

12. What is the difference between Proc and lambda?

Proc and Lambdas are closures and we have been using closures, since block is a closure too. For e.g. enumerable

(1..10).each{|x| puts x}

But there are differences among each of these

13. Explain block and yield with an example?

def my_method(&block)
block.call(5) if block_given?
end
my_method do |x|
x * x
end
=> 25
def my_m
yield if block_given?
end
my_m {puts "Block"}
=> Block

These are generally the questions asked about Ruby. There is another topic from which questions are asked i.e. Rack, we will covering this in the next segment and post that we will move to Rails.

Ruby Devs

Written by

Ruby Devs

The things we encounter daily as rubyists and sometimes while switching jobs :p

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade