Service management through the for control structure.

The module is a proof-of-concept to investigate the abuse of the for structure to implement various services.

The idea is that, with a for, the service-provider can:

  • control the end of the service (thus can finalize things like releasing ressources)
  • communicate data with the user on each iteration; the used can also communicate results to the provider.

Introduced classes

class CompareQuery[E: nullable Object]

for_abuse :: CompareQuery

A comparison query.
interface ForAbuser[E: nullable Object]

for_abuse :: ForAbuser

Encapsulation of service in a for-compatible interface.

Redefined classes

redef class Array[E: nullable Object]

for_abuse :: for_abuse $ Array

Resizable one dimension array of objects.
redef class Sys

for_abuse :: for_abuse $ Sys

The main class of the program.

All class definitions

redef class Array[E: nullable Object]

for_abuse :: for_abuse $ Array

Resizable one dimension array of objects.
class CompareQuery[E: nullable Object]

for_abuse $ CompareQuery

A comparison query.
interface ForAbuser[E: nullable Object]

for_abuse $ ForAbuser

Encapsulation of service in a for-compatible interface.
redef class Sys

for_abuse :: for_abuse $ Sys

The main class of the program.
package_diagram for_abuse::for_abuse for_abuse core core for_abuse::for_abuse->core a_star-m a_star-m a_star-m->for_abuse::for_abuse

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module array

core :: array

This module introduces the standard array structure.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.

Children

module a_star-m

a_star-m

# Service management through the `for` control structure.
#
# The module is a proof-of-concept to investigate the abuse of
# the `for` structure to implement various services.
#
# The idea is that, with a `for`, the service-provider can:
# * control the end of the service (thus can finalize things
#   like releasing ressources)
# * communicate data with the user on each iteration; the used can
#   also communicate results to the provider.
module for_abuse

# Encapsulation of service in a `for`-compatible interface.
#
# The service is not effectively started until the iterate method
# is called. Then, each step of the iteration is a step in the service.
#
# While, for a typing point of view, abusers are just classes with an
# iterator method, the point of this class is to tag services that return
# a ForAbuser object.
#
# Note that using having `ForAbuser` as a genuine subclass of `Collection`
# works but is not recommended since it may cause mental health issues.
interface ForAbuser[E]
	# Starts and control the service
	fun iterator: Iterator[E] is abstract
end

# Abuser to read a file, see `file_open`
private class ReadFileForAbuser
	super ForAbuser[FileReader]
	var path: String
	redef fun iterator do return new ReadFileForAbuserIterator(path)
end

# Abuser iterator to read a file, see `file_open`
private class ReadFileForAbuserIterator
	super Iterator[FileReader]
	var path: String
	redef var item: FileReader is noinit
	redef var is_ok = true
	init
	do
		# start of service is to open the file, and return in
		item = new FileReader.open(path)
	end
	redef fun next
	do
		# end of service is to close the file
		# there is only one iteration
		is_ok = false
		item.close
	end
end

####

# A comparison query.
# The user is asked to compare `a` with `b` then set `res` accordingly.
#
# * if `a < b` then the user sets `res` to -1
# * if `a > b` then the user sets `res` to 1
# * if `a == b` then the user sets `res` to 0
#
# It is the responsibility of the user to implement a total order.
# ie. the implemented comparison must be asymmetric, transitive and total.
class CompareQuery[E]
	# The first element to compare
	var a: E
	# The second element to compare
	var b: E
	# The result of the comparison (according to the user)
	var res = 0 is writable
end

# Abuser for sorting array, see `sort_fa`
private class SortAbuser[E]
	super ForAbuser[CompareQuery[E]]
	var array: Array[E]
	redef fun iterator do return new SortAbuserIterator[E](array)
end

# Abuser iterator for sorting array, see `sort_fa`
# Implements a sort by permutation
private class SortAbuserIterator[E]
	super Iterator[CompareQuery[E]]
	# The index of the big loop
	var i: Int = 0
	# The index of the small loop
	var j: Int = 0
	# The array to sort
	var array: Array[E]
	# The query used to communicate with the user.
	# For ecological concerns, a unique CompareQuery is instatiated.
	var query: nullable CompareQuery[E] = null
	redef fun item do return query.as(not null)
	init
	do
		# Initialize the algorithm, see `next` for the rest
		if not is_ok then return
		query = new CompareQuery[E](array[i], array[j])
	end
	redef fun is_ok do return i < array.length - 1
	redef fun next
	do
		# Process the last query
		if item.res > 0 then
			var tmp = array[i]
			array[i] = array[j]
			array[j] = tmp
		end
		# Get the next iteration
		j += 1
		if j >= array.length then
			# End of small loop
			i += 1
			j = i + 1
		end
		if not is_ok then return
		# Prepare the next query
		item.a = array[i]
		item.b = array[j]
		item.res = 0
	end
end

redef class Array[E]
	# Sort an array through a `for` abuse.
	# The user uses the provided query (item) to implements its own comparison
	#
	#     var a = [1, 3, 2]
	#     for q in a.sort_fa do q.res = q.a <=> q.b
	#     assert a ==  [1, 2, 3]
	#
	# Implements a sort by permutation.
	fun sort_fa: ForAbuser[CompareQuery[E]]
	do
		return new SortAbuser[E](self)
	end
end

####

# Open and read a file through a `for` abuse.
# The abuse just ensures that the file is closed after the reading.
#
#     for f in file_open("/etc/issue") do
#         var l = f.read_line
#         print l
#         assert not l.is_empty
#     end # f is automatically closed here
fun file_open(path: String): ForAbuser[FileReader]
do
	return new ReadFileForAbuser(path)
end
lib/for_abuse/for_abuse.nit:11,1--165,3