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
  attr_reader :type
  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 Smile 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 Smile
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 Smile
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 Wink
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)
- inlining support with any(),all(),one(), and non(), which like the init method support nil loading, array loading and/or block value evaluation
- 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.

» Go to Registration page
Page 1 of 1
» 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

 

Advertisement