Archive for the ‘Ruby’ Category

Ruby Debugger Things I Always Forget

Sunday, August 24th, 2008

Continuing on a theme seen about Perl. Basic commands are not covered ( list , print, continue, etc. )

  1. Install rdebug: sudo gem install rdebug -y

  2. Open a session: rdebug script

  3. Always show a listing after every command: set autolist

  4. Show a variable consistently: display variableName

  5. …or the result of a method on a variable: display variableName.methodName

  6. Conditional break…conditionally: break ./fileName:lineNumer [if condition]

  7. See where you are in the stack ( especially handy if you like recursion, like me ): where

  8. Move up/down in the stack: up/down

  9. Go to the nth frame in the stack: frame n

    (more…)

OK I said that you conjugate the verb fully, but that’s not entirely true. As I’ve not yet learned the subjunctive system, I’m limited to the indicative present and perfect systems. I’ve also included the participles as well as the infinitives.

Might I add that linguistic and string processing with Ruby is a pleasure. Many Years (tm) ago I tried this is French with Java and it was an unholy pain.

Can anyone guess where I’m going with these last few posts?

  • Simplified macron-based entry ( \={a}, \={e}, etc.)
  • Process simplified text to UTF-8 ( the language of rails )
  • Code to process these strings into full conjugations
  • Rails as a display engine

What do you think I’m making?

BTW: This code is very much rough draft, it’s enough to handle the ideas, but needs more modularization and more refactoring, so this is not “steven at his best” level code

(more…)

When I write my Latin homework in LaTeX, the source winds up looking like this:

\item[13.] Am\={\i}c\={o}s tr\={\i}st\={e}s exc\={e}pit, ad m\={e}nsam inv\={\i}t\={a}vit, et e\={\i}s perfugium ac s\={o}l\={a}cium h\={\i}c dedit.

{ Aside: You might be thinking that entering “\ = { \ i }” just to get a single character would be a drag, but thanks to Textmate I have created snippets such that Control + letter does all that typing for me }

Now if I want to post this to the web, I need to convert those characters from say “\={\i}” to “\ī”. I would like it to go through the sentence and change each of those LaTeX-macron characters to HTML entities.

Similarly, I occasionally have need to convert LaTeX-macron sequences to UTF-8 codes.

And yet other times I want it to convert those codes to macron-ized characters.

So I wrote a script that takes input of the LaTeX form and will let you specify if you want the output in HTML entity (default), macron characters, or utf8 characters.

The best part is that I’ve written this function into Textmate as an extension so for me conversion is:

Default String

ss_tmlatinconv_1

Highlight the LaTeX string

tm_latinconv_2

Choose my command with this script in it

ss_tmlatinconv_3

Text is replaced, magically!

ss_tmlatinconv_4

And it looks like this in a browser…

\item[13.] Amīcōs trīstēs excēpit, ad mēnsam invītāvit, et eīs perfugium ac sōlācium hī

Previously I had shown how I had used Ruby to re-create passive system conjugations. I decided I’d try to add on some functionality and I’ve come up with a Ruby script that handles full verbal system conjugation for 1st and 2nd conjugations (-āre / -ēre) in Latin.

I’ll ultimately build this into a Rails application, but I’m getting the design and debug out of the way with a ruby script.

Check out the code on my tracking page. I need to add support for 3, 3-io, and 4th, but I’m amazed by how light this code has come up to be ( ~ 300 lines with generous whitespace! ).

I’m pretty pleased with my recursive macron validation scheme. Showing off recursive code ( for non Lisp people ) is sorta like being a white guy demonstrating your breakdancing skills. You’re embarrassed to try, you’re embarrased with the result, but even if you do it a little bit, you feel way proud of yourself ( probably too much ).

My printfs aren’t aligning as you see in the output. If there are any printf gurus that can help me let me know.

This started off as a bit of an amusement just to see if i could show the elegance of Ruby — and find a way to help me memorize the suffix-addition-heuristics that characterize inflected languages like Latin.

As usual, it quickly became much more than that.

Known Issue:

The macrons are slightly off, particularly in the 3rd person plural ( no vowel before ‘nt’ should ever be lengthened ). I’ll write a fixer routine soon.

[code lang="ruby"]
#!/usr/bin/env ruby
class Verb < Object
  attr_reader :firstpersonform, :infinitive, 
              :perfectstem, :passperfpart, :stem
  def initialize(initString)
    (@firstpersonform, @infinitive, 
       @perfectstem, @passperfpart)=initString.split(/,\s+/)
    pparts=initString.split(/,\s+/)
    @passive_endings = ["r", "ris", "tur", 
                        "mur", "min\xc4\xab", "ntur"]
    @personages = ["First Singular", "Second Singular", 
                   "Third Singular",
                   "First Plural", "Second Plural", "Third Plural"]
  end
  def stem
    # For efficiency, if the iVar @stem is defined, don't go 
    # through this structure
    return @stem unless @stem.nil?
    if @infinitive =~ /?re$/
      return @stem = @infinitive.gsub(/(.*)?re$/,'\\1?')
    end
    if @infinitive =~ /?re$/
      return @stem = @infinitive.gsub(/(.*)?re$/,'\\1?')
    end    
  end
  def to_s
    return "#{self.firstpersonform} #{self.infinitive} 
       #{self.perfectstem} #{self.passperfpart}"
  end
  def present_passive
    local_pe=@passive_endings.clone
    return [@firstpersonform + "r", 
      local_pe[1..-1].map{|x| self.stem + x}].flatten!
  end
  def imperfect_passive
    imperfect_stem = self.stem + "b\xc4\x81"
    return @passive_endings.map{|x| "#{imperfect_stem}#{x}"}
  end
  def future_passive
    fp_stem=self.stem+"bi"
    standards = @passive_endings[2..-1].map{|x| fp_stem + x}
    return [@stem + "b\xc5\x8d", @stem + "beris", standards].flatten!
  end
  def passive_system
    p_sys_hash= { :label=>@personages,
                  :present => self.present_passive,
                  :imperfect => self.imperfect_passive,
                  :future => self.future_passive}
    0.upto(5) do |index|
      printf("%-15s %-10s %-16s %s\n", 
                      p_sys_hash[:label][index],
                       p_sys_hash[:present][index],
                       p_sys_hash[:imperfect][index],
                       p_sys_hash[:future][index]
                      )
    end
    puts "\n\n"
  end
end
[/code]
    x=Verb.new("laudō, laudāre, laudāvī, laudatus")
    puts x
    x.passive_system

    y=Verb.new("moneō monēre, monuī, monitus")
    puts y
    y.passive_system

And the output?

    laudō laudāre laudāvī laudatus
    First Singular  laudōr    laudābār       laudābō
    Second Singular laudāris  laudābāris     laudāberis
    Third Singular  laudātur  laudābātur     laudābitur
    First Plural    laudāmur  laudābāmur     laudābimur
    Second Plural   laudāminī laudābāminī   laudābiminī
    Third Plural    laudāntur laudābāntur    laudābintur


    moneō monēre monuī monitus
    First Singular  moneōr    monēbār        monēbō
    Second Singular monēris   monēbāris      monēberis
    Third Singular  monētur   monēbātur      monēbitur
    First Plural    monēmur   monēbāmur      monēbimur
    Second Plural   monēminī monēbāminī    monēbiminī
    Third Plural    monēntur  monēbāntur     monēbintur

I don’t think that you have to be a Ruby guru to see that Ruby code is incredibly tight. Interestingly enough, Latin, as according to the gospel of Wheelocki, is taught in a very programmatic heuristic manner. You’re taught to carry a certain data file of critical givens on your biological hard drive ( a verb has 4 principal parts, the principal parts of “to praise” …. ) and then are taught a series of transformations to be performed on those 4 principal parts. Working those out is an exercise being a mental computer, mutating data according to heuristic and spitting it out.

Interestingly, when printing technology was much more expensive ( or, students were much more rebellion-prone when forced to pay outrageous prices for books ) Latin instruction was a few terse rules and the homework was “Write out the application of these heuristics to the following data items”. With the rules, and the given inputs, the human scribbler would write out the references he would need to be able to advance to the next chapter.

I have a certain admiration for this method.

But I also have ruby, and remembering how i applied a few map()s or flatten!() statements is just as good.

[code lang="ruby"]
irb(main):001:0> "capture to here!  leave this off".gsub(/(.*\!).*(\s+.*)$/, "\\1 and \\2")
=> "capture to here! and  off"
[/code]

I looked in my Pickaxe, I looked in various tutorials, but this simple little thing hung me up more than many other Ruby questions I’ve had over the years.

[Rails] Associations

Monday, January 14th, 2008

Yesterday I found out I had made a major boo-boo in setting up an ActiveRecord::Association.

Imagine a “Widget” model that is composited of serveral other fields. You might think to yourself.

“An Widget has a SKU ( housed in table ‘skus’ based on model SKU ), a widget has a color, etc.”

You then might model your code such that

    Widget < ActiveRecord::Base
      has_one :sku
      has_one :color
    end

And accordingly

    SKU < ActiveRecord::Base
      belongs_to :widget
    end

This is wrong.

You must think in terms of the most “atomic” element. What’s the relationship of a SKU? A SKU “has one” product to which it is applicable. You see, what you’ve done above is absolutely reverse of the way it should be.

Think this way:

    SKU < ActiveRecord::Base
      has_one :widget
    end

And then just add the mirror entry, for completeness

    Widget < ActiveRecord::Base
      belongs_to :sku
    end

You can see this explained in the Rails API:

class Employee < ActiveRecord::Base
    has_one :o ffice
end

class Office < ActiveRecord::Base
   belongs_to :employee    # foreign key - employee_id
end

If you find yourself using the primary key of the composite entity to find something in the the constituent table or getting into weird sorts of problems with .create() or find yourself thinking that you may need to implement something like (although it is pretty cool):

    $ irb
    irb(main):001:0> class K
    irb(main):002:1> end
    => nil
    irb(main):003:0> k1 = K.new
    => #
    irb(main):004:0> k2 = eval('K').new
    => #
    irb(main):005:0> k3 = Object.const_get('K').new
    => #

[Reference]

The real difficulty here is with how English speakers construe the transitivity of the phrase “has one”. Does this mean:

  • X is a superior containing entity i.e. “contains” (“The happy meal has one hamburger and one toy”)
  • X is uniquely assigned in a relationship (“The parolee has one parole officer”)

The word “relationship” in the second bullet is the use of “has_one” that Rails uses the phrase “has_one” to signify.

If, when getting your object model to work in Rails seems really hard and sorta backwards, you should say “this seems needlessly hard, maybe I’m doing it the wrong way” and bail out of that design. The LOLCatz rules apply here: “Using Rails to make your life easy - ur doin’ it wrong

[Rails] Cleaning up HABTM views (2/2)

Friday, January 11th, 2008

You may want to see the previous entry on this topic. We’ll be using that application.

The reality is that most people use Rails for web frameworks … the console manipulation stuff we explored in the previous post doesn’t really help us much. We need a web interface. While using the script/generate gave us some scaffolds that we can play with ( http://localhost:3000/candies or ../flavors ), it’s not really “integrated” and it doesn’t quite demonstrate the “has many”-ness.

First we’ll fire up the web server (script/server) and see what the ‘new’ view looks like:

ss2.

Hm, that’s certainly not giving us any place to enter some flavorful information. Let’s fix that in the view.

(more…)

This is the mail that I sent to Rails-list which describes my issues around the Rails scaffolding in Rails 2.0. Extensive debugging information can be found in my diagnostic research post.


Hello,

I’ve read the (many) re-posts about problems around scaffolding in Rails 2.0 and have followed a number of tutorials and fully understand “how to scaffold” from a technical perspective, but I don’t understand the mindset of how to use the new scaffolding. It seems like a productivity- / agility- regress and I’m thinking I may have failed to properly grok the new setup. In the interest of full disclosure, I’m coming back to Rails after being in other toolkits for about 9 months.

Thanks to the intrepid work of Sean Lynch at ( http://fairleads.blogspot.com/2007/12/rails-20-and-scaffolding-step-by-step.html ) I found a tutorial that would familiarize me with the raw “how to scaffold” material.

I followed his tutorial’s step of:

“ruby script/generate scaffold Movie”

Great! From that point I filled in the “columns” in the migration as I had done in Rails 1.x. All I should need to do is run “rake db:migrate” and try adding a new record via the dynamically-created view.

When I started the server and navigated localhost:3000/movies I had the “create new” button. When I pushed that button there were no text widgets to enter despite having defined the columns that corresponded to said widgets having been added to the migration ( I have a lengthy blog post about how my diagnostics went, for anyone else’s edification ). In short the scaffold that had been created knew nothing of the columns I had added in the migration and, as such, the ‘new’ view had no widgets.

This struck me as well, wrong. On Sean’s post another user confirms the same experience. I have tried it with sqlite3 / mysql / postgres connectors.

Research showed that the scaffold had remained static relative to the time that I had done the original aenemic invocation. Per “script/generate scaffold —help”:

./script/generate scaffold post` # no attributes, view will be anemic

To fix this I had to re-issue the script/generate command with all the attributes in “final draft” mode ( “script/generate scaffold movie title:string text:description one_sheet_url:string” ) and then over-write the old templates ( output stored below, for legibility, Fig. 1).

The solution implies:

  • You have to get the script/generate command’s “attributes” arguments perfect at time of creation OR
  • You do this overwriting thing that I describe below.

As I recall Rails 1.x’s dynamic scaffolding allowed us to use a scaffold flexibly strictly based on migrations and rake db:migrate. This flexibility allowed us to “sketch” ideas very rapidly. Or is it considered a “Good Thing” that you get a “perfected” “generate scaffold” command at some point? If so, what’s the reasoning? Am I missing some sort of rake command that “refreshes” the scaffold templates?

Based on the comments at Sean’s site and some of the questions in the comments to DHH’s Rails 2. announcement I think there are others grappling with this quandry as well. Can anyone help?

Steven

(more…)

I decided to spend some of my Christmas break taking a look at Ruby on Rails again and trying to get an application together under this application stack. Since I last looked at Rails, it had crossed the 1.x to 2.x version marker and several changes manifested. For someone trying to follow the 1.x tutorials or the canonical reference book Agile Web Development With Rails, one doesn’t make very much progress before the changes with respect to scaffolding bite one. One may need a bit of a tutorial on Rails 2.x scaffolding before being “pretty close” to training documentation. An excellent tutorial for this content was found at [Fairleads][fl].

Yet as I followed this through, I found myself stymied by the same error reported by “James”

Thanks now I easily understand how scaffolding changed in 2.0.

But I still have a problem when I followed the tutorial everything went fine but i am not presented with any sort of fields to enter information.

And when i add stuff to the database by hand and I list from within the scaffold I am not getting the information that is entered into the database I am just getting a blank entry.

At first I thought my problem was that I was trying to use a PostgreSQL back end, or perhaps it was because I was using MySQL, etc. But nevertheless I still ran into the same problem no matter which db back-end I used.

I then found another tutorial at [SapphireSteel][ss]. Curiously, this worked ( the db back end was sqlite3 ). This tutorial is meant to show off the Sapphire Steel product, but Huw, the author, has added, graciously, a “here’s what Rails is doing on the back end” translation for each step that his product automates.

With these data points my working hypothesis was this:

  • Use SQLite3
  • Follow Huw’s instructions, which use a more specialized invocation of “script/generate scaffold” ( control )
  • Duplicate these instructions using a more primitive invocation of “script-generate scaffold” that’s more familiar ( experiment )

    (more…)