Module: Stud
- Extended by:
- Stud
- Included in:
- Stud
- Defined in:
- lib/stud/secret.rb,
lib/stud/try.rb,
lib/stud/pool.rb,
lib/stud/task.rb,
lib/stud/time.rb,
lib/stud/trap.rb,
lib/stud/with.rb,
lib/stud/buffer.rb,
lib/stud/interval.rb,
lib/stud/benchmark.rb,
lib/stud/temporary.rb,
lib/stud/benchmark/rusage.rb
Overview
A class for holding a secret. The main goal is to prevent the common mistake of accidentally logging or printing passwords or other secrets.
See <github.com/jordansissel/software-patterns/blob/master/dont-log-secrets/ruby/> for a discussion of why this implementation is useful.
Defined Under Namespace
Modules: Benchmark, Buffer, Temporary, Time, With Classes: Pool, Secret, Task, Try
Constant Summary collapse
- TRY =
class Stud::Try
Try.new
Class Method Summary collapse
-
.interval(time, &block) ⇒ Object
This implementation tries to keep clock more accurately.
-
.simulate_signal(signal) ⇒ Object
Simulate a signal.
-
.trap(signal, &block) ⇒ Object
Bind a block to be called when a certain signal is received.
-
.untrap(signal, id) ⇒ Object
Remove a previously set signal trap.
Instance Method Summary collapse
-
#interval(time, &block) ⇒ Object
def interval.
-
#try(enumerable = Stud::Try::FOREVER, &block) ⇒ Object
A simple try method for the common case.
Class Method Details
.interval(time, &block) ⇒ Object
This implementation tries to keep clock more accurately. Prior implementations still permitted skew, where as this one will attempt to correct for skew.
The execution patterns of this method should be that the start time of ‘block.call’ should always be at time T*interval
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/stud/interval.rb', line 8 def self.interval(time, &block) start = Time.now while true block.call duration = Time.now - start # Sleep only if the duration was less than the time interval if duration < time sleep(time - duration) start += time else # Duration exceeded interval time, reset the clock and do not sleep. start = Time.now end end # loop forever end |
.simulate_signal(signal) ⇒ Object
Simulate a signal. This lets you force an interrupt without sending a signal to yourself.
44 45 46 47 |
# File 'lib/stud/trap.rb', line 44 def self.simulate_signal(signal) #puts "Simulate: #{signal} w/ #{@traps[signal].count} callbacks" @traps[signal].each(&:call) end |
.trap(signal, &block) ⇒ Object
Bind a block to be called when a certain signal is received.
Same arguments to Signal::trap.
The behavior of this method is different than Signal::trap because multiple handlers can request notification for the same signal.
For example, this is valid:
Stud.trap("INT") { puts "Hello" }
Stud.trap("INT") { puts "World" }
When SIGINT is received, both callbacks will be invoked, in order.
This helps avoid the situation where a library traps a signal outside of your control.
If something has already used Signal::trap, that callback will be saved and scheduled the same way as any other Stud::trap.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/stud/trap.rb', line 21 def self.trap(signal, &block) @traps ||= Hash.new { |h,k| h[k] = [] } if !@traps.include?(signal) # First trap call for this signal, tell ruby to invoke us. previous_trap = Signal::trap(signal) { simulate_signal(signal) } # If there was a previous trap (via Kernel#trap) set, make sure we remember it. if previous_trap.is_a?(Proc) # MRI's default traps are "DEFAULT" string # JRuby's default traps are Procs with a source_location of "(internal") if RUBY_ENGINE != "jruby" || previous_trap.source_location.first != "(internal)" @traps[signal] << previous_trap end end end @traps[signal] << block return block.object_id end |
.untrap(signal, id) ⇒ Object
Remove a previously set signal trap.
‘signal’ is the name of the signal (“INT”, etc) ‘id’ is the value returned by a previous Stud.trap() call
53 54 55 |
# File 'lib/stud/trap.rb', line 53 def self.untrap(signal, id) @traps[signal].delete_if { |block| block.object_id == id } end |
Instance Method Details
#interval(time, &block) ⇒ Object
def interval
24 25 26 |
# File 'lib/stud/interval.rb', line 24 def interval(time, &block) return Stud.interval(time, &block) end |
#try(enumerable = Stud::Try::FOREVER, &block) ⇒ Object
A simple try method for the common case.
118 119 120 |
# File 'lib/stud/try.rb', line 118 def try(enumerable=Stud::Try::FOREVER, &block) return TRY.try(enumerable, &block) end |