PullMonkey Blog


31 Jan

Rounding to the nearest number in Ruby


A while ago, I was taking a look at a problem on the rails forum. This post was submitted to find the best solution to round any number to the nearest multiple of 10. For example, this method would take the number 6 and return 10, or the number 29 and return 30. So the first thing that popped into my mind was modulus. We can use modulus to determine how far we are from the nearest multiple of 10. Meaning that if we are given 19 and we want to know how close we are to the nearest 10, we can simple do 19 % 10, which will return 9, and 10 - 9 is 1, so we are 1 away from the nearest 10 spot. Here is that method, assuming only Fixnum, so it is implemented as an extension of the Fixnum class:

1
2
3
4
5
6
7
8

class Fixnum
  def roundup
    return self if self % 10 == 0   # already a factor of 10
    return self + 10 - (self % 10)  # go to nearest factor 10
  end
end 

While this did the job, it was suggested that it would be better if things happened.

  1. Use the Numeric class (this class encompasses Float, Fixnum and Integer)
  2. Don't limit the method to just the nearest 10, have it as a parameter
  3. And an added bonus - rounddown()



Here is the resulting code (defaulting to 10):

1
2
3
4
5
6
7
8
9
10

class Numeric
  def roundup(nearest=10)
    self % nearest == 0 ? self : self + nearest - (self % nearest)
  end
  def rounddown(nearest=10)
    self % nearest == 0 ? self : self - (self % nearest)
  end
end 

Well that is pretty cool, here is some sample output from using this method:

1
2
3
4
5
6
7
8
9

puts 2.roundup    #=> 10
puts 23.roundup   #=> 30
puts 20.roundup   #=> 20
puts 45.roundup   #=> 50
puts 156.roundup  #=> 160 
puts 156.34.roundup   #=> 160.0
puts 16.34.roundup    #=> 20.0
puts 81.1234.roundup  #=> 90.0 


6 Responses Filed under: Home, development, ruby Tags:
06 Jan

Convert a Ruby hash into a class object


I first saw the need to convert a hash object to a class when answering this post.

In the post, the user wanted to load a YAML object into his hash and then present the data from the hash in a form. Needless to say it was not very DRY the way it had to be implemented. So I started looking into it, I found this. This solution was a great starting point for where I ended up, but it was not general enough, it was hard coded, plus it was missing the getters and setters. So it turns out that in ruby it wasn't too much trouble to convert a hash into a class object. So let's get started:

I have implemented this for use in Rails, so let's start with the model that does all the magic:

1
2
3
4
5
6
7
8
9
10
11

class Hashit
  def initialize(hash)
    hash.each do |k,v|
      self.instance_variable_set("@#{k}", v)  ## create and initialize an instance variable for this key/value pair
      self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})  ## create the getter that returns the instance variable
      self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("@#{k}", v)})  ## create the setter that sets the instance variable
    end
  end
end

Notice the self.class.send(:define_method ...) rather than self.define_method, this is a hack to overcome the fact that define_method() is private. I had come across this when trying to figure out the post mentioned above. Found the information to solve this here.

Ok, so on to the Controller that creates the Hashit object:

1
2
3
4
5
6
7
8
9

class TestItController < ApplicationController
  def index
    hashit = {:support_email  => "test@test.com",
              :allow_comments => 0}
    @hashit  = Hashit.new(hashit)
  end
end

Well that is easy, pass in a hash and get an object. Here is what @hashit looks like at this point:

1
2

#<Hashit:0xb6a65110 @allow_comments=0, @support_email="test@test.com">

And of course, now the view, what we wanted to clean up and make more elegant. Here is what the user started with:

Note: In this example @hashit is an actual hash, not a class object.

1
2
3
4
5
6

<% form_tag :action => 'config', :method => :post do %>
  <%= text_field 'settings',  'support_email', :size => 20, :value => @hashit['support_email']%>
  ...
<% end %>

And here is what our view code looks like now:

1
2
3
4
5

<% form_for :hashit, :url => {:action => 'index'} do |f| %>
  <%= f.text_field :support_email %>
<% end %>

Much simpler, DRYer :)

Well that is pretty much it, I suppose the next step would be to have a save method that updates the hash? This way we can do @hashit.save() and it will return a new hash that you can use. Well actually, that probably isn't too hard, lets see if I can do it real quick, class object back to hash ...

Well, I am back and I was able to figure it out, here is the new class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

class Hashit
  def initialize(hash)
    hash.each do |k,v|
      self.instance_variable_set("@#{k}", v)
      self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})
      self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("@#{k}", v)})
    end
  end

  def save
    hash_to_return = {}
    self.instance_variables.each do |var|
      hash_to_return[var.gsub("@","")] = self.instance_variable_get(var)
    end
    return hash_to_return
  end
end

Just added the save() method, that takes all the instance variables and sets them as keys in our new hash. So here is the outcome of our save():

1
2

{"support_email"=>"new@some_email", "allow_comments"=>0}


22 Responses Filed under: Home, development, rails, ruby Tags:
05 Jan

OpenGL in the browser


Neat, this is just from the examples, more to come with opengl when I get a chance.

Check out this guy's opengl stuff, really cool!

This requires java applet support, and I can say that it works wonderfully in Linux/FireFox, and Alias (from above) says that it works with IE. So there you have it.





Use your mouse and move it around ....


type="application/x-java-applet"
archive="/processing/RGBCube/RGBCube.jar"
width="200" height="200"
standby="Loading Processing software..." >
codebase="http://java.sun.com/update/1.4.2/jinstall-1_4_2_12-windows-i586.cab"
width="200" height="200"
standby="Loading Processing software..." >


This browser does not have a Java Plug-in.


Get the latest Java Plug-in here.




Built with Processing


04 Jan

Open Flash Chart Plugin for Ruby on Rails



Update: Version 2 of Open Flash Chart is available. Examples for version 2 are here.



I just finished converting the latest version of Open Flash Chart over to ruby, for use with rails.

Check out what I can do now :) Like the google analytics graphs.

Scatter Chart



width="500" height="300" id="ie_chart_17" align="middle"> type="application/x-shockwave-flash" pluginpage="http://ww.macromedia.com/go/getflashplayer" id="chart_17"/>



View Source Code






More examples can be found on my Open Flash Chart Projects page.

Don't forget to check out the original - http://teethgrinder.co.uk/open-flash-chart/.