Yesterday I decided I needed a break from calculator programming for a day or two, so I decided to have another practice with Ruby.  Somehow, looking up a substitute for Bignums in Ruby brought me to the Perl 6 specifications over time.  When I was glancing over the specs, I noticed that it introduced the module Quantum::Superposition as an official part of the language.  This module defined the use of Junctions in Perl.  I didn't know what a junction was before it, but once I learned it seemed like a decently cool idea.  Therefore, I decided to write my own module for Junctions in Ruby written the Ruby Way.

For those who haven't heard of them: Junctions are data types that are treated like a single value but in reality occupy multiple values, much like in quantum theory certain molecules can occupy superpositions -- they can occupy different spatial areas concurrently.  Junctions are to be treated as single values that are determined based on their rules (based on ANY and ALL declarations) but can be expanded out to evaluate contents when wanted.  When a Junction is going by an exclusive-all ruleset, all values have to be true when evaluated in an expression to give true; when going on an exclusive-any ruleset, if any of the values give true, then it gives a true value.  They can also be mixed so that to obtain a true at least a certain number of values must come out as true.

Anyways, here's the class I wrote for Ruby Junctions.  No RDoc yet cause I'm lazy with commenting, but it kinda speaks for itself.  I cheated a bit and basically held the overall value in an array and made specific evaluation methods, but it works perfectly so its hard to complain:

Code:
class Junction
attr_accessor :value, :coelements
ANY = "|";ALL = "&"
def initialize(num_of_values,typeof,array=nil)
if block_given?
index = 0;@value = Array.new(num_of_values){|value|
yield value, index;index+=1}
elsif array;@value = array
else;@coelements = (@value = Array.new(num_of_values)).size.to_i
end
@coelements = @value.size.to_i
@type = (typeof=="any" or typeof=="all")?
((typeof=="any")?ANY: ALL):
((typeof==ANY)?ANY: ALL) #always defaults to ALL if not valid
end
def forall
if block_given?
index = 0;while index < coelements
yield @value.at(index), index;index+=1
end
else;raise "No block given to \'forall\' method"
end
end
def ==(value)
if @type==ANY
return @value.include?(value)
elsif @type==ALL
return (@value==value)?true:false
else;raise "Unknown Junction Typing error in \'==\' method"
end
end
def !=(value)
if @type==ANY
return !(@value.include?(value))
elsif @type==ALL
return (@value==value)?false:true
else;raise "Unknown Junction Typing error in \'==\' method"
end
end
def <(value)
return @value.max < value
end
def >(value)
return @value.min > value
end
def <=(value)
return @value.max <= value
end
def >=(value)
return @value.min >= value
end
def ===(value)
return (@value.include?(value) and @value.at(@value.index(value))===value)
end
def to_a#override
return @value.to_a
end
def to_s#override
return @value.to_s.gsub(", ",((@type==ANY)?ANY: ALL))
end
def to_i
@value.each {|i|(i = (i.to_i)) rescue i = 0}.to_a;return self
end
def to_f
@value.each {|i|(i = (i.to_f)) rescue i = 0.0}.to_a;return self
end
def <<(value)
@value.push(value);return self
end
def push_to_last(value)
@value.push(value);return self
end
def pop_last!
return @value.pop
end
def pop_last_array!
@value.pop;return self
end
def type_change(new_type=nil)
if new_type;@type = new_type
else;@type = ((@type==ANY)?ALL: ANY)
end
end
def elements?
@coelements.to_i
end
def clean!
@value.uniq!;return self
end
def pretty_puts #not needed, but cool for easy reading :3
self.forall {|i,j|puts "#{(j+1).to_s}" <<
format_number_th(j) << " possible value is #{i.to_s}" }
end
private#helpers
def format_number_th(j)#helper for pretty_puts
if [10,11,12].include?(j%100);return "th"
else;return (["st","nd","rd","th"].at((j%10>=4)?3:j%10)).to_s
end
end
end

And with the test code:

Code:
superpos = Junction.new 5,Junction::ANY,[1,2,3,4,5]

superpos.pretty_puts
puts superpos.to_s
puts superpos.to_i.to_s
puts superpos.to_a.to_s
puts (superpos << 6).to_s
puts superpos.pop_last_array!.to_s
puts superpos == 3 #all
superpos.type_change
puts superpos == 3 #any
puts superpos.to_s

superpos.forall{|value,coelement_i|
puts "\\o/ hai mr.#{value} from #{coelement_i} I liek chocolat mikl"
}

I get:

Code:
1st value is 1
2nd value is 2
3rd value is 3
4th value is 4
5th value is 5
[1|2|3|4|5]
[1|2|3|4|5]
[1, 2, 3, 4, 5]
[1|2|3|4|5|6]
[1|2|3|4|5]
false
true
[1&2&3&4&5]
\o/ hai mr.1 from 0 I liek chocolat mikl
\o/ hai mr.2 from 1 I liek chocolat mikl
\o/ hai mr.3 from 2 I liek chocolat mikl
\o/ hai mr.4 from 3 I liek chocolat mikl
\o/ hai mr.5 from 4 I liek chocolat mikl

So I can confirm that instances of Junction are treated like they're supposed to according to the specifications for ALL and ANY specifications.  I'm thinking of adding a SOM sub-type where you can specify non-completeness of ANY and ALL mixes, such as [1&2&3|4|5] which isn't exactly how the Perl one goes, but this isn't Perl I'm doing this in, is it?  Anyways, while at the moment it's not quite as useful as the Perl version (it's mostly only useful for standard-type instances and doesn't fare well with supplying a form of generic like it can be used in Perl), it at least gave my a decent programming practice, and might shorten some of my code that makes use of the class by using junctions instead of Arrays with constant element checking.

Anyways, for other people who use Ruby, I'd like to hear any ideas you have for me concerning additions and fixes right now I don't have that many standard methods for Junctions yet, but any that anyone would like to provide would be appreciated.
That's pretty neat, I had never heard of these before. Here's a page describing their use in Perl, in case anyone wants to read more about it:
http://en.wikibooks.org/wiki/Perl_6_Programming/Junctions
If I'm understanding it right, it's just a quick way to do multiple comparisons. Is that right?
Yeah, its very useful for multiple comparisons all in one, but can also be used in Perl in a way to form generics (though my implementations is far off from being that flexible at the moment). Cool to see you think its cool
This is pretty neat, I hadn't heard of anything like this before. I haven't used Ruby for anything, though I had read about the language specifics. Good job
Hmm, I found that there is already a Ruby Junction project on RubyForge already, that is a LOT more sugary syntactically -- however, it has few methods for non-evaluatory functions, so I think mine is still a good supplement to it, and if nothing else I find mine easier to use for my own personal works
Well, I looked over the documentation for the one on RubyForge (not the source mind you I don't know how Apache SVN works well enough to even get the code from the repo x.x yeah I suck) and realized:

- it's lame and only supports inlining instances with any(), all(), and none(), no support for full instances with easy evaluation (though when it comes to instantiation syntax it gives you a syntax sugar rush)
- it hasn't been updated since '08 and is in early alpha form
- it doesn't have that great of documentation
- it has only 9 code views..

And so I decided that I wanted to be more serious about my implementation and maybe get further than them. With that, I now have quintupled the size of the source (AKA pastebinning so Kerm doesn't maul me) and added these features:

- added ONE, NON, and NIL rulesets (nil means that no ruleset was given and therefore doesn't return an evaluation with an applied rule)
- fixed comparison operators concerning Junction Instances (most of them besides == an != only evaluated with the ANY ruleset)
- fixed to_s, to_i, and to_f
- optimized (haha yes Ruby is slow but there are tricks to faster evaluation and execution of code) using crazy use of embedded and chained ternary operators

.. and a few more things I forgot about. Anyways, source:

http://pastebin.com/WnL5UDcA
Cool deal, dude. You should get this up on something like RubyForge.

Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

»
» All times are UTC - 5 Hours

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum