Search code examples
rubyprivateinjectclearance

Troubles when reading clearance source code


def initialize_sign_in_guard_stack
  default_guard = DefaultSignInGuard.new(self)    
  guards = Clearance.configuration.sign_in_guards 

  guards.inject(default_guard) do |stack, guard_class|
    guard_class.new(self, stack)         
  end
end

class DefaultSignInGuard < SignInGuard
  def call
    if session.signed_in?
      success
    else
      failure default_failure_message.html_safe
    end
 end
end

class SignInGuard
  def initialize(session, stack = [])
    @session = session
    @stack = stack
  end
private
attr_reader :stack, :session

def signed_in?
  session.signed_in?
end

def current_user
  session.current_user
end
end

Pry(main)> Clearance.configuration.sign_in_guards # => []

No. 1

Since guards is an empty array, so what the guard_class refers to? And how could it run the new method? Can you explain what does this line of code do?

No. 2

signed_in? is a private method of SignInGuard. I know that only 'self' can call it. Here, session.signed_in? Why does it make sense?


Solution

  • No1: To nothing. The block will never execute when you call it on an empty array, therefore a value will not be assigned. It is like asking what is item in [].each { |item| puts item }. The idea is when it is not empty to create objects of a list of guard classes. Then guard_class will refer to each individual guard class.

    No2: You can't call private methods with explicit receiver, even if it is self. However, here signed_in? called on session is Session#signed_in?, not SignInGuard#signed_in?, which is public so it is fine.