DEV Community

Cover image for Ruby interview questions
Andrew Molchanov
Andrew Molchanov

Posted on

Ruby interview questions

In this post, I've created a collection of Ruby basics for a Middle-level developer.

In common cases, interviewers have a pre-prepared set of tasks. While others prefer a conversation about experience mixed with technical questions. On the other hand, some companies care most about soft skills. But all of these understand one thing correctly. An interview is a costly process. All companies want to decrease costs.

After interviewing for many companies, there is an understanding that the candidate should know and be able to apply the basic principles on which modern applications are built. Although in my practice there has been no such thing as an interview ending after the first wrong answer, there are basics that need to be understood ahead of time.

A Junior developer is not tied to the programming language in any way, but a Senior can write more complex code. Then if you can solve these problems without any hints, most of the practical preparation for the Middle position is passed and you can focus on other topics during preparing for an interview.

1. Implement the method Array#map

A possible answer
class Array def map return unless block_given? result = [] i = 0 while self[i] do result << yield(self[i]) i += 1 end result end end 
Enter fullscreen mode Exit fullscreen mode

Checking the usage

[1,2,3,4].map { |x| x * 10 } 
Enter fullscreen mode Exit fullscreen mode

2. Implement the method attr_accessor

A possible answer
module AttrAccessor def self.included(klass) klass.extend(ClassMethods) end module ClassMethods def custom_attr_accessor(*args) args.each do |arg| define_method(arg) do self.instance_variable_get("@#{arg}") end define_method("#{arg}=") do |value| self.instance_variable_set("@#{arg}", value) end end end end end 
Enter fullscreen mode Exit fullscreen mode

Checking the usage

class Car include AttrAccessor custom_attr_accessor :wheels_count, :driver_name end car = Car.new car.wheels_count = 4 car.wheels_count car.driver_name = 'Kevin' car.driver_name 
Enter fullscreen mode Exit fullscreen mode

3. Refactor the code by removing ifs

class HtmlFormatter def initialize(body) @body = body end def to_s "<body>#{@body}</body>" end end class JsonFormatter def initialize(body) @body = body end def to_s "{ body: #{@body} }" end end class Text def initialize(body) @body = body end def formatted(type=nil) if type == :json JsonFormatter.new(@body) elsif type == :html HtmlFormatter.new(@body) else raise 'an unknown format type' end end end 
Enter fullscreen mode Exit fullscreen mode

A possible answer
class Text def initialize(body, formatter) @body = body @formatter = formatter end def formatted @formatter.render(@body) end end class BaseFormatter def render(text) raise 'Not implemented :render method' end end class HtmlFormatter < BaseFormatter def render(text) "<body>#{text}</body>" end end class JsonFormatter < BaseFormatter def render(text) "{ body: #{text} }" end end class XmlFormatter < BaseFormatter end 
Enter fullscreen mode Exit fullscreen mode

Checking the usage

text = Text.new('Text', JsonFormatter.new) puts text.formatted 
Enter fullscreen mode Exit fullscreen mode

4. Write a code which help a command (1..10).select(&3) return [3, 6, 9]

A possible answer
class Fixnum def to_proc Proc.new { |item| item % self == 0 } end end 
Enter fullscreen mode Exit fullscreen mode

5. There is a code

class Post attr_reader :state, :title, :body def initialize(title, body) @title = title @body = body @state = :draft end def publish! @state = :published if @state == :draft end def delete! @state = :deleted if @state == :published end end 
Enter fullscreen mode Exit fullscreen mode

Extend the functionality of the class Post which allows changing any attribute of an instance of Post.
For example, Post.new.force_title('An awesome article') will be correct.

A possible answer
module Forceable def method_missing(method, *args, &block) if method =~ /force_(\w+)/ && previous_value = self.instance_variable_get("@#{$1}") self.instance_variable_set("@#{$1}", args.first) puts "Post changes #{$1} value from #{previous_value} to #{args.first}" else super end end end Post.include(Forceable) 
Enter fullscreen mode Exit fullscreen mode

Checking the usage

post = Post.new('Title', 'Body') post.force_state(:draft) p post.state 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)