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
Checking the usageA 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
[1,2,3,4].map { |x| x * 10 }
2. Implement the method attr_accessor
Checking the usageA 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
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
3. Refactor the code by removing if
s
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
Checking the usageA 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
text = Text.new('Text', JsonFormatter.new) puts text.formatted
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
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
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.
Checking the usageA 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)
post = Post.new('Title', 'Body') post.force_state(:draft) p post.state
Top comments (0)