File: annotation.rb

package info (click to toggle)
ruby-fiber-annotation 0.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 92 kB
  • sloc: ruby: 35; makefile: 4
file content (58 lines) | stat: -rw-r--r-- 1,555 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2023, by Samuel Williams.

require 'fiber'

class Fiber
	# A mechanism for annotating fibers.
	module Annotation
		# Annotate the current fiber with the given annotation.
		# @parameter annotation [Object] The annotation to set.
		def initialize(annotation: nil, **options, &block)
			@annotation = annotation
			super(**options, &block)
		end
		
		# Get the current annotation.
		# @returns [Object] The current annotation.
		attr_accessor :annotation
		
		# Annotate the current fiber with the given annotation.
		#
		# If a block is given, the annotation is set for the duration of the block and then restored to the previous value.
		#
		# The block form of this method should only be invoked on the current fiber.
		#
		# @parameter annotation [Object] The annotation to set.
		# @yields {} The block to execute with the given annotation.
		# @returns [Object] The return value of the block.
		def annotate(annotation)
			if block_given?
				raise "Cannot annotation a different fiber!" unless Fiber.current == self
				
				begin
					current_annotation = @annotation
					@annotation = annotation
					return yield
				ensure
					@annotation = current_annotation
				end
			else
				@annotation = annotation
			end
		end
	end
end

unless Fiber.method_defined?(:annotation)
	Fiber.prepend(Fiber::Annotation)
	
	# @scope Fiber
	# @name self.annotate
	# Annotate the current fiber with the given annotation.
	def Fiber.annotate(...)
		Fiber.current.annotate(...)
	end
end