Files
mruby-mruby/mrbgems/mruby-set
Yukihiro "Matz" Matsumoto 8f7bfa4f68 mruby-set: convert kset_copy_* macros to functions
Convert kset_copy_merge and kset_copy_replace from macros to static
functions for better maintainability and debugging.

Benefits:
- Better debugging: can set breakpoints and step through code
- Improved type safety: proper function parameter checking
- Cleaner code: no macro expansion bloat at call sites
- Better error messages: meaningful function names in stack traces
- Easier maintenance: functions are simpler to modify than complex macros

The operations are substantial enough (memory allocation, loops with GC
management) that function call overhead is negligible compared to the
actual work performed.

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-14 10:53:03 +09:00
..
2022-10-22 08:31:38 +10:00

mruby-set

mruby-set provides a Set class for mruby, offering a collection of unordered, unique elements. It's useful when you need to store a group of items and quickly check for membership, or perform set operations like union, intersection, and difference.

Installation

To use mruby-set in your mruby project, add the following to your build_config.rb:

conf.gem "#{MRUBY_ROOT}/mrbgems/mruby-set"

Or, if you have it as a separate gem:

conf.gem :github => "mruby/mruby-set"

Usage and Examples

Creating a Set

You can create a set from an array or by using the Set.[] shorthand:

require 'set' # Not strictly necessary in mruby if compiled in

set1 = Set.new([1, 2, 3])
#=> Set[1, 2, 3]

set2 = Set[3, 4, 5]
#=> Set[3, 4, 5]

Adding and Deleting Elements

s = Set.new
s.add(10)    #=> Set[10]
s << 20      #=> Set[10, 20]
s.add?(30)   #=> Set[10, 20, 30]
s.add?(20)   #=> nil (20 is already in the set)

s.delete(10) #=> Set[20, 30]
s.delete?(5) #=> nil (5 was not in the set)
s.delete?(20) #=> Set[30]

Set Operations

mruby-set supports common set operations:

Union (|, +, union): Returns a new set containing all elements from both sets.

set_a = Set[1, 2, 3]
set_b = Set[3, 4, 5]

set_a | set_b  #=> Set[1, 2, 3, 4, 5]
set_a + set_b  #=> Set[1, 2, 3, 4, 5]

Intersection (&, intersection): Returns a new set containing elements common to both sets.

set_a = Set[1, 2, 3]
set_b = Set[3, 4, 5]

set_a & set_b  #=> Set[3]

Difference (-, difference): Returns a new set containing elements from the first set that are not in the second set.

set_a = Set[1, 2, 3]
set_b = Set[3, 4, 5]

set_a - set_b  #=> Set[1, 2]

Exclusive OR (^): Returns a new set containing elements that are in one or the other of the sets, but not in both.

set_a = Set[1, 2, 3]
set_b = Set[3, 4, 5]

set_a ^ set_b  #=> Set[1, 2, 4, 5]

Querying the Set

Checking for inclusion (include?, member?, ===):

s = Set["apple", "banana", "cherry"]
s.include?("banana")  #=> true
s.member?("grape")    #=> false

Checking size (size, length):

s = Set[10, 20, 30]
s.size #=> 3

Checking if empty (empty?):

Set.new.empty? #=> true
Set[1].empty?  #=> false

Subset and Superset (subset?, superset?, <, <=, >, >=):

set_main = Set[1, 2, 3, 4]
sub = Set[2, 3]
super_set = Set[1, 2, 3, 4, 5]

sub.subset?(set_main)         #=> true
set_main.superset?(sub)       #=> true
set_main < super_set          #=> true (proper subset)
super_set > set_main          #=> true (proper superset)
Set[1,2].proper_subset?(Set[1,2,3]) #=> true
Set[1,2,3].proper_superset?(Set[1,2]) #=> true

Disjoint (disjoint?): Returns true if the set has no elements in common with the given set.

Set[1, 2].disjoint?(Set[3, 4]) #=> true
Set[1, 2].disjoint?(Set[2, 3]) #=> false

Intersect (intersect?): Returns true if the set has any elements in common with the given set.

Set[1, 2].intersect?(Set[2, 3]) #=> true
Set[1, 2].intersect?(Set[3, 4]) #=> false

Other Useful Methods

Convert to Array (to_a):

s = Set["a", "b", "c"]
s.to_a #=> ["a", "b", "c"] (order may vary)

Iterating (each):

s = Set[1, 2, 3]
s.each { |x| puts x * 10 }
# Output:
# 10
# 20
# 30

Map/Collect (map!, collect!): Modifies the set by applying the block to each element.

s = Set[1, 2, 3]
s.map! { |x| x * x } #=> Set[1, 4, 9]

Select/Filter (select!, filter!): Keeps elements for which the block returns true.

s = Set[1, 2, 3, 4, 5]
s.select! { |x| x.even? } #=> Set[2, 4]

Reject (reject!): Deletes elements for which the block returns true.

s = Set[1, 2, 3, 4, 5]
s.reject! { |x| x.odd? } #=> Set[2, 4]

Clear (clear): Removes all elements from the set.

s = Set[1, 2, 3]
s.clear #=> Set[]

Replace (replace): Replaces the contents of the set with the contents of the given enumerable.

s = Set[1, 2, 3]
s.replace([4, 5]) #=> Set[4, 5]

Flatten (flatten, flatten!): Returns a new set that is a copy of the set, flattening any nested sets. flatten! modifies the set in place.

s = Set[1, Set[2, 3], 4]
s.flatten #=> Set[1, 2, 3, 4]

Method Overview

Here's a list of commonly used methods available in mruby-set:

  • Set.[](*ary)
  • initialize(enum = nil, &block)
  • size, length
  • empty?
  • clear
  • replace(enum)
  • to_a
  • include?(o), member?(o), ===
  • superset?(set), >=
  • proper_superset?(set), >
  • subset?(set), <=
  • proper_subset?(set), <
  • intersect?(set)
  • disjoint?(set)
  • each(&block)
  • add(o), <<(o)
  • add?(o)
  • delete(o)
  • delete?(o)
  • delete_if { |o| ... }
  • keep_if { |o| ... }
  • collect! { |o| ... }, map! { |o| ... }
  • reject! { |o| ... }
  • select! { |o| ... }, filter! { |o| ... }
  • merge(enum)
  • subtract(enum)
  • |(enum), +(enum), union(enum)
  • -(enum), difference(enum)
  • &(enum), intersection(enum)
  • ^(enum)
  • ==(other)
  • hash
  • eql?(o)
  • classify { |o| ... }
  • divide(&func)
  • join(separator = nil)
  • inspect, to_s
  • flatten, flatten!

Limitations

These methods are not implemented yet:

  • freeze
  • to_set
  • divide(Set#divide with 2 arity block is not implemented.)

License

Under the MIT License: