views:

316

answers:

3

I have a small ruby application I wrote that's an anagram searcher. It's for learning ruby, but I would like to put it up online for personal use. I have some experience with Rails, and many here have recommended Sinatra. I'm fine with either, but I cannot find any information on how to use a text file instead of a database. Is there a good tutorial on how to do this somewhere, or can anhyone offer any tips?

The application is quite simple, validates against a text file of a word list, then finds all anagrams. I have been assuming that this should be quite simple, but I'm stuck on importing that textfile into Rails (or Sinatra if i choose that way). In the Rails project, I have placed the textfile in the lib directory.

Unfortunately, even though the path appears to be correct in Rails, I get an error:

no such file to load -- /Users/court/Sites/cvtest/lib/english.txt

(cvtest is the name of the rails project)

Here is the code. It works great by itself:

file_path = '/Users/court/Sites/anagram/dictionary/english.txt'

input_string = gets.chomp


# validate input to list
if File.foreach(file_path) {|x| break x if x.chomp == input_string}

  #break down the word
  word = input_string.split(//).sort 

  # match word  
  anagrams = IO.readlines(file_path).partition{
    |line| line.strip!
    (line.size == word.size && line.split(//).sort == word)
  }[0] 

  #list all words except the original
    anagrams.each{ |matched_word| puts matched_word unless matched_word == input_string } 


#display error if 
else
  puts "This word cannot be found in the dictionary"
end
+4  A: 

Factor the actual functionality (finding the anagrams) into a method. Call that method from your Web app.

In Rails, you'd create a controller action that calls that method instead of ActiveRecord. In Sinatra, you'd just create a route that calls the method. Here's a Sinatra example:

get '/word/:input'
  anagrams = find_anagrams(params[:input])
  anagrams.join(", ")
end

Then, when you access the http://yourapp.com/word/pool, it will print "loop, polo".

Chuck
+2  A: 

With sinatra, you can do anything. These examples doesn't even require sinatra, you could roll your own rack interface thing.

require 'rubygems'
require 'sinatra'
require 'yaml'

documents = YAML::load_file("your_data.yml")

Or:

require 'rubygems'
require 'sinatra'
content = Dir[File.join(__DIR__, "content/*.textile)].map {|path|
  content = RedCloth(File.read(path)).to_html
}

Etcetera.

August Lilleaas
+4  A: 

I know the question is marked as answered, but I prefer the following, as it uses query parameters rather than path based parameters, which means you can pass the parameters in using a regular GET form submission:

require 'rubygems'
require 'sinatra'

def find_anagrams word
  # your anagram method here
end

get '/anagram' do
  @word = params['word']
  @anagrams = find_anagrams @word if @word
  haml :anagram
end

And the following haml (you could use whatever template language you prefer). This will give you an input form, and show the list of anagrams if a word has been provided and an anagram list has been generated:

%h1 
  Enter a word
  %form{:action => "anagram"}
    %input{:type => "text", :name => "word"}
    %input{:type => "submit"}
- if @word
  %h1 
    Anagrams of 
    &= @word
  - if @anagrams
    %ul
      - @anagrams.each do |word|
        %li&= word
  - else
    %p No anagrams found
Brian Campbell