Class: Console::Resolver

Inherits:
Object
  • Object
show all
Defined in:
lib/console/resolver.rb

Overview

Represents a class resolver that can be used to set log levels for different classes as they become available.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeResolver

Create a new class resolver.



63
64
65
66
67
# File 'lib/console/resolver.rb', line 63

def initialize
	@names = {}
	
	@trace_point = TracePoint.new(:class, &self.method(:resolve))
end

Class Method Details

.default_resolver(logger, env = ENV) ⇒ Object

You can change the log level for different classes using CONSOLE_$LEVEL env vars.

e.g. ‘CONSOLE_WARN=Acorn,Banana CONSOLE_DEBUG=Cat` will set the log level for the classes Acorn and Banana to `warn` and Cat to `debug`. This overrides the default log level.

You can enable all log levels for a given class by using ‘CONSOLE_ON=MyClass`. Similarly you can disable all logging using `CONSOLE_OFF=MyClass`.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/console/resolver.rb', line 22

def self.default_resolver(logger, env = ENV)
	# Find all CONSOLE_$LEVEL variables from environment:
	levels = logger.class::LEVELS
		.map{|label, level| [level, env["CONSOLE_#{label.upcase}"]&.split(",")]}
		.to_h
		.compact
	
	off_klasses = env["CONSOLE_OFF"]&.split(",")
	on_klasses = env["CONSOLE_ON"]&.split(",")
	
	resolver = nil
	
	# If we have any levels, then create a class resolver, and each time a class is resolved, set the log level for that class to the specified level:
	if on_klasses&.any?
		resolver ||= Resolver.new
		
		resolver.bind(on_klasses) do |klass|
			logger.enable(klass, logger.class::MINIMUM_LEVEL - 1)
		end
	end
	
	if off_klasses&.any?
		resolver ||= Resolver.new
		
		resolver.bind(off_klasses) do |klass|
			logger.disable(klass)
		end
	end
	
	levels.each do |level, names|
		resolver ||= Resolver.new
		
		resolver.bind(names) do |klass|
			logger.enable(klass, level)
		end
	end
	
	return resolver
end

Instance Method Details

#bind(names, &block) ⇒ Object

Bind the given class names to the given block. When the class name is resolved into an actual class, the block will be called with the class as an argument.

If the class is already defined, the block will be called immediately.

If the class is not defined, the block will be called when the class is defined, using a trace point.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/console/resolver.rb', line 77

def bind(names, &block)
	names.each do |name|
		if klass = Object.const_get(name) rescue nil
			yield klass
		else
			@names[name] = block
		end
	end
	
	if @names.any?
		@trace_point.enable
	else
		@trace_point.disable
	end
end

#resolve(trace_point) ⇒ Object

Invoked by the trace point when a class is defined.

This will call the block associated with the class name, if any, and remove it from the list of names to resolve.

If the list of names is empty, the trace point will be disabled.



105
106
107
108
109
110
111
112
113
# File 'lib/console/resolver.rb', line 105

def resolve(trace_point)
	if block = @names.delete(trace_point.self.to_s)
		block.call(trace_point.self)
	end
	
	if @names.empty?
		@trace_point.disable
	end
end

#waiting?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/console/resolver.rb', line 94

def waiting?
	@trace_point.enabled?
end