# Setfu Purpose: A general purpose object implementing sets. Construction: Set.new >> creates an empty set Set.new(p) >> creates a set initialized with elements p Set.new.add!(p) >> chained with #add method ::parameter p:: "abcxyz" >> ordinate values of each character added to set 'a'..'z' >> ordinate values of each range element added to set [6,19,'g'..'k'] >> items in an array added to set (recursively) 375 >> element number `375` added to set or set instance [v0,v1,...].to_set >> converts array to set instance ::array values:: set instance array literal, array instance >> recursive values must comply to first-level rules string literal, string instance range literal, range instance positive small integers including zero, integer instance "a7P".to_set >> converts ordinate values of each char to set members ('a'..'k').to_set >> converts ordinate values of each char in range to set members parenthesis needed for literal. parenthesis not needed for instance variable Operators: a < b >> true if `a` is a "proper" subset of `b` ... a !=b and a in b a <= b >> true if `a` is a subset of `b` a - b >> set difference ... removes elements from a found in b a & b >> set intersection a | b >> set union a ^ b >> exclusive union s == a >> equality ... both sets contain exactly the same elements a === s >> case equality ... where `s` applies to case variable, and `a` applies to when clause see: .set_case(sym) for additonal configuration s != a >> inequality ... sets are different ~a >> inversion a ** b >> intersection test ... true if one or more elements are common to both sets s[i] >> true if 'i' is an element of the set s[i]=k >> if k==true, adds element `i` to set, otherwise removes element `i` from set where a,b === instances of Set, String, Array, Range s === instance of Set i === member index ... positive integer (0,1,2,3...) or char ('a') character indexes use #ord to convert to integer k === boolean Methods: .count >> returns number of elements in set .each_member {block} >> iterates on element ordinate of each element in set .add!(p) >> includes additional members to current set .include?(p) >> true if `p` is a subset of current set .empty? >> true if there are no elements in set .zap! >> removes all elements of set and resets entropy to zero .add_parse_chars! >> adds [0..47, 58..64, 91..96, 123..126] to set .dup >> creates a copy of the current set .to_i >> returns internal integer representing all bits of the set space .to_s >> returns a string representation of all elements .to_a >> returns an array of all elements (in integers) .set_bits!(n) >> replaces set with each set bit of integer `n` ... negative numbers are not allowed! .recalculate_entropy! >> calculates new entropy value based on current elements on set. recommended to call this method after #set_bits! is called. not necessary to be called for normal operation. Returns newly calculated entropy. .min >> returns element of smallest ordinate value, or nil if empty set .max >> returns element of highest ordinate value, or nil if empty set .to_set >> returns self ... Also exported to String, Range, and Array which creates an instance of Set .set_case(sym) >> sets case--when behavior as follows: :mode_equal (default) case(s) -> when a ... validates on a ==s :mode_intersection case(s) -> when a ... validates on a ** s :mode_sub case(s) -> when a ... validates on a <= s :mode_proper case(s) -> when a ... validates on a < s :mode_super case(s) -> when a ... validates on s <= a :mode_superproper case(s) -> when a ... validates on s < a Properties: .entropy >> Total number of possible states. Like the universe, can only get bigger. Can be set to a higher number. Property may be read. ## Installation Add this line to your application's Gemfile: gem 'setfu' And then execute: $ bundle Or install it yourself as: $ gem install setfu ## Usage The Set class defines a group of positive integers including zero. Unlike the array, there is no implied order to each element of the set other than their chronological order implied by their ordinate value. Each set instance may not duplicate elements. The upper bounds of an element is only limited to the size of (1 << element) that a Bignum may hold. Performance degrades with elements larger than 65536. This is due to the amount of processing required to operate on large integers. One bit of storage is required to hold all possible values a set may hold. Internally, a Bignum instance is used to hold all the bits up to the highest ordinate value. Sets can simplify many programming paradigms. Instead of writing code like this: def valid_password_chars(str) str.each_char do |ch| return false unless (ch>='a' && ch <='z') || (ch>='A' && ch <='Z') || (ch>='0' && ch <='9') || (ch=='#') || (ch=='_') || (ch=='!') end return true end valid_password_chars "Not a valid password at all!" # false valid_password_chars "Secret#15_!" # true You can instead do this: valid_char_set = Set.new ['a'..'z','A'..'Z','0'..'9','#','_','!'] "Not a valid password at all!" <= valid_char_set # false "Secret#15_!" <= valid_char_set # true Depending on the operator, the string expression above is converted in to a set instance. Fast bitwise math is then performed internally. Sets can often offer improved performance over regular expressions and arrays. This is possible thanks to very fast bit-wise operations on its internal Bignum representation. Each bit represents a placeholder for a possible element. Sets can be used within case statements. The entire case statement can be configured to use one of six different comparison modes. The case variable defines the modes of operation for the entire case statement. An alternate configuration is to set the same comparison modes on each when clause. Note that the case variable takes precedence over each and every when clause. The case variable must be of type `Set`. The left side of the comparison is always the case variable. An example is as follows: case [2,4,6..13].to_set.set_case(:mode_sub) when [1..31] puts "subset detected!" end In ruby, case statements use the `===` operator when evaluating the when clause. The `case` variable sits on the left, and the `when` clause sits on the right. The Set class overloads the `===` operator and decides what operations are performed on the left and right side of the operator. The `#set_case` method takes one of six symbol arguments to perform one of 6 comparison modes. Comparison modes can be set on either the left or the right, but the right takes precedence. ## Contributing 1. Fork it 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new Pull Request