|
|||||||||||||||||||||||||||||||||||||||||||||
|
About...
www.flickr.com
This is a Flickr badge showing public photos from joeyGibson. Make your own badge here.
Previous Entries
Categories
Search
Blosxom Plugins
|
Fri, Jun 17 2005
Ruby + MySQL + Windows = SUCCESS! (Finally)
If you do a Google for "ruby mysql windows" you will find, among other
things, lots of people trying to use Ruby to access MySQL on a Windows system. I've been
trying for some time, and have finally gotten things going.
About a year ago I found this article in which he fought the same fight. He was able to get a working .so file, using the .Net C++ compiler, and offered his binary, but that won't work for everyone. Specifically, a file compiled with VC7 isn't usable by VC6 (at least not that I could see). Anyway, I followed his advice to a point, and then started experimenting. I opened up irb and started poking MKMF to see what I could accomplish. What I finally ended up with is a hacked extconf.rb that can be edited easily to get the library built on your own system. It will work with both VC6 and VC7, by changing one line in the file. Assuming that you have MySQL 4.1 installed in the default location, and you are using VC6, and Ruby 1.8.2 is installed in the default location, you should be able to do this ruby extconf.rb nmake nmake installand have everything compile and install. Notice that I said should. You should still take a look at the file, near the top, to see if the settings are appropriate for your system. Once installed, you can use this module directly, or install DBI for that "standard" interface. DBI will use the library you just built and installed, so all you have to do is download the DBI module, then do this cd ruby-dbi-all ruby setup.rb config --with=dbi,dbd_mysql ruby setup.rb setup ruby setup.rb installIf you want to install other DBD drivers, add them after dbd_mysql. That should be in. Here's the hacked extconf.rb file. There are only two lines you might need to change, and they are at the top of the file with comments around them. I have tested this slightly using the binary I built with VC6 and it seems to work fine. I have not tested the VC7-compiled binary, because I don't have a Ruby distro that was compiled with VC7. Let me know if these directions don't work for you. Not that I can do anything about it, but I could put a note here for others. Also, notice that I used 8.3 pathnames, which is really ugly. I would have been happy to use the pathnames with spaces, but VC6 doesn't like spaces in pathnames. VC7 can grok them fine, but not 6. Both understand the 8.3, so it was just easier to use that. One more thing. I don't believe that installing Visual Studio.Net installs the necessary header and library files for building non-.Net binaries. IOW, you might not have windows.h which will cause things not to work. If you download and install the Platform SDK, then you'll be fine. My extconf.rb will add the default Platform SDK directory to the necessary paths, so if you have that installed, and try to do a VC7 build, you should be ok. [/tech/ruby] # | | Sun, Oct 03 2004
Today is Day Three of RubyConf2004 and I'm
tired. This has been a good conference. Lots of stuff to think about
and play with. Lots of code flying around and lots of laptops all in
one room. I was up until 02:00 this morning working on an ADO adapter
for Active
Record in order to talk to SQL Server. I've
got about 40 failing tests right now (out of 143) so I'm closing
in on finishing... It's been interesting. I only just began looking at
Active Record yesterday morning, so I think I'm doing pretty
well. Active Record is an OR framework in Ruby that is really
simple to work with. Very cool. It's part of the Rails suite, which
is an MVC framework for
building websites in Ruby. Very intriguing.
[/tech/ruby] # | | Thu, Apr 22 2004
The second meeting of the Atlanta Ruby
User Group will be next Tuesday, April 27 at
7:00PM. We will continue with my introduction to Ruby presentation and discuss what
others have been working on since the last meeting. I also have a few
fairly cool demos to show.
[/tech/ruby] # | | Mon, Mar 08 2004
If you read my stuff very often then you know that I am a
huge fan of the Ruby
programming language. I write a ton of Ruby code and went to RubyConf 2003, so there was only
one other direction to take my love of Ruby: start a user group. So, I
have started the Atlanta Ruby User
Group. Our first meeting will be Tuesday, March 30 2004, at my
office in Norcross. There is a map at the web site and a mailing list. Rather than try to
restate the meeting announcement, I'm just going to
repost the email I sent to the mailing list here. If you want more info,
drop me an email and/or visit
the group site. If you are within
range of Atlanta, please come on out for the meeting.
Our first meeting will be Tuesday March 30 at 7:00 PM. The meeting location is at my office in Norcross, on Peachtree Industrial Blvd. There is a map on the website. We have classrooms, so it will be a comfortable environment. [/tech/ruby] # | | Wed, Jan 07 2004
OpenSSH, that ships with Cygwin has a nice utility called ssh-agent. This program
is a daemon that will hold on to your keys so that hosts you are
authorized to log on to will not continually ask for your
password. This is especially useful when working with CVS repositories over SSH. When you
run ssh-agent, it spits out text that should be evaluated to set two
environment variables that you will need in order to run ssh-add, to
actually add your keys to it. That output looks like this:
SSH_AUTH_SOCK=/tmp/ssh-mjKjm512/agent.512; export SSH_AUTH_SOCK; SSH_AGENT_PID=1600; export SSH_AGENT_PID; echo Agent pid 1600;On a Unix system, it's easy to capture the output of ssh-agent and evaluate it, but under the 'command shell' that ships with Windows systems, which is so patheticly crippled that my old Commodore 64's BASIC-based shell is looking pretty good, you can't do that. So what are those poor saps, myself included, who are using Windows systems to do? Ruby to the rescue. I wrote a simple script that executes ssh-agent, capturing the output, massaging it a little, and then creating a batch file that I can run to set the necessary variables. Simply redirecting the output to a batch file won't work because there are some Unix-isms, such as exporting the variables, that don't work on Windows. So, here's the script:
1 #!ruby
2
3 lines = %x{ssh-agent}
4
5 File.open("c:/tmp/sde.bat", "w") do |file|
6 lines.each do |line|
7 chunks = line.chomp.split ';'
8
9 if chunks[0] =~ /^SSH/
10 file.puts "SET #{chunks[0]}"
11 end
12 end
13 end
You can see that the script sends the captured and massaged output to a
batch file called "sde.bat" located in C:/tmp. You can change both of
these to suit your preference. Once the script runs, I simply execute
the generated batch file and then run ssh-add. The nice thing about
the generated batch file is that it lingers until the next time I run
the Ruby script. Thus as I open new console Windows I can re-run it to
get the environment variables set properly in each one.
[/tech/ruby] # | | Wed, Sep 17 2003
After reading several threads about the text
scrmabler and various implementations, I revised my Ruby version and it's now 21 lines
shorter and much more Ruby-like. It makes far less of an
attempt to deal with punctuation, but I think that's OK. This
is just a lark, after all.
1 class Mixer
2 private
3 def randomize(str)
4 return str if str.length < 4
5
6 str =~ /\B.*\B/
7 first = $`
8 last = $'
9 first + ($&.split(//).sort_by {rand}.join) + last
10 end
11
12 public
13 def mix_file(filename)
14 lines = IO.readlines(filename)
15
16 mix_lines(lines)
17 end
18
19 def mix_string(str)
20 mix_lines(str.split).join(" ")
21 end
22
23 def mix_lines(lines)
24 lines.collect! do |line|
25 words = Array.new
26
27 line.split(/\W/).each do |word|
28 words << randomize(word)
29 end
30
31 words.join(" ")
32 end
33 end
34 end
[/tech/ruby] # | | Mon, Sep 15 2003
By Popular Demand, I Give You... Mixer!
"Popular demand," yeah... right... That's the ticket. Anyway, I saw this blog
entry by Jamie this morning which
caused me to write a Ruby
program to mix up the letters of words, leaving the first and last
letter as they were. I started out with a simple script, then I added
better punctuation support, then I converted it to a class, then I
wrote unit tests to run it. Anyway, somebody wanted to see it, so here it
is. Is it great code? Probably not. Do I care? Not really.
1 class Mixer 2 private 3 def randomize(str) 4 if str.length < 4 5 return str 6 end 7 8 letters = str.split(//) 9 10 first = letters[0] 11 mid = letters[1..(letters.length - 2)] 12 last = letters[letters.length - 1] 13 14 new_letters = "" 15 16 while mid && mid.length > 0 17 len = mid.length 18 r = rand(len) 19 new_letters << mid.delete_at(r) 20 end 21 22 first + new_letters + last 23 end 24 25 public 26 def mix_file(filename) 27 lines = IO.readlines(filename) 28 29 mix_lines(lines) 30 end 31 32 def mix_string(str) 33 new_str = "" 34 35 mix_lines(str.split).each do |line| 36 new_str << line 37 end 38 39 new_str 40 end 41 42 def mix_lines(lines) 43 lines.collect! do |line| 44 new_line = "" 45 46 line.split(/\s+|,|\.|\!|\(|\)|\"|\'/).each do |word| 47 new_line << randomize(word) << " " 48 end 49 50 new_line 51 end 52 53 lines 54 end 55 end And the unit tests, which don't actually test anything.
1 require 'test/unit'
2 require 'mix'
3
4 class MixTest < Test::Unit::TestCase
5 def setup()
6 @mixer = Mixer.new
7 end
8
9 def test_word()
10 x = @mixer.mix_string("testing")
11 puts x
12 assert_not_equal("testing", x, "String not randomized")
13 end
14
15 def test_string()
16 x = @mixer.mix_string("this is a humongous test, dangit")
17 puts x
18 end
19
20 def test_file()
21 article = @mixer.mix_file("testfile.txt")
22 #puts article
23 end
24 end
I'm sure someone will find this useful... Again, "yeah, right." Ah well, it was a mildly amusing diversion... [/tech/ruby] # | | Tue, Jul 08 2003
Mike Clark
this morning has a
bit of a nudge for Rael
to give Ruby a try. Mike makes
the following
statement
that I completely agree with
The beauty of Ruby is its simplicity and consistency. With Ruby, I find myself writing code to get the job done rather than to appease the compiler.So true! Since Ruby is a dynamic language, there are no variable types to declare, no static checking; variables are just slots. The number of lines of Ruby code to do something is far less than the equivalent Java code, and I would argue more readable. You don't have to jump through hoops to make the compiler happy, you just write your code to do what you need done. That's it. It's a beautiful thing. The fact that regular expressions are baked right into the language is also a giant plus. This is how Perl does it, and Matz basically lifted this approach when he created Ruby. Python's regex support is not nearly as nice since you have to create a regex and call methods on it instead of using a regex literal and using special variables to get the groups, etc. Where having baked-in regex support really shines is in not having to escape backslashed atoms in the regex. Regexen in Java are even more difficult to read than usual because every backslash is doubled to keep the Java string parser from barfing on unknown escapes. [/tech/ruby] # | | Fri, Jun 27 2003
I took a swipe at implementing Dave
Thomas' Kata 6 which is an assignment dealing with anagrams. The goal is to
parse a list of 45000-ish words, finding all the words that are
anagrams of other words in the file. Dave claims there are 2,530 sets
of anagrams, but I only got 2,506. I'm not sure where the disconnect
is, but here's my solution. I welcome any comments and critiques.
words = IO.readlines("wordlist.txt")
anagrams = Hash.new([])
words.each do |word|
base = Array.new
word.chomp!.downcase!
word.each_byte do |byte|
base << byte.chr
end
base.sort!
anagrams[base.to_s] |= [word]
end
# Find the anagrams by eliminating those with only one word
anagrams.reject! {|k, v| v.length == 1}
values = anagrams.values.sort do |a, b|
b.length <=> a.length
end
File.open("anagrams.txt", "w") do |file|
values.each do |line|
file.puts(line.join(", "))
end
end
largest = anagrams.keys.max do |a, b|
a.length <=> b.length
end
puts "Total: #{anagrams.length}" #
puts "Largest set of anagrams: #{values[0].inspect}" #
print "Longest anagram: #{anagrams[largest].inspect} " #
puts "at #{largest.length} characters each"
Update: Of course, 10 seconds after uploading the code, I see something I could change. Instead of sorting the anagram hash descending by array length, I could have done the following:
longest = anagrams.to_a.max do |a, b|
a[1].length <=> b[1].length
end
This will sort and pull the largest one off. The key is bucket 0 and the interesting array is in bucket 1. [/tech/ruby] # | | Fri, Jun 20 2003
Dave Thomas of the Pragmatic
Programmers has started publishing programming problems, calling
them Kata.
He's just published Kata
8 this morning and I've had a go at a solution. The problem is to
take a supplied list of words and go through it finding all the six
letter words that are constructed from shorter words in the file. The
full problem is to write the program in three different ways: one
optimized for human consumption, one optimized for speed, and one that
is highly extensible.
Presented below is my first cut at this kata. I think it is fairly readable, at 79 lines, so this probably will count as my "fit for human consumption" version. It's relatively fast, completing in 11 seconds. Comments? Critiques?
#!/usr/local/bin/ruby
start = Time.now
# Arrays for each class of word
fourLetters = Array.new
threeLetters = Array.new
twoLetters = Array.new
sixLetters = Array.new
# Loop over the word list, segregating the words
# to their respective array
IO.foreach("wordlist.txt") do |line|
line.chomp!.downcase!
case line.length
when 2
twoLetters << line
when 3
threeLetters << line
when 4
fourLetters << line
when 6
sixLetters << line
end
end
candidates = Array.new
# Build up all combinations of four letters + two letters
# and store in them as candidates
fourLetters.each do |four|
twoLetters.each do |two|
wc = four + two
candidates << wc
end
end
# Build up all combinations of three letters + three
# letters and store them as candidates
threeLetters.each do |three|
threeLetters.each do |otherThree|
wc = three + otherThree
candidates << wc
end
end
# Finally, all combinations of two letters + two letters
# + two letters and store those as candidates
twoLetters.each do |firstTwo|
twoLetters.each do |secondTwo|
twoLetters.each do |thirdTwo|
wc = firstTwo + secondTwo + thirdTwo
candidates << wc
end
end
end
# Now get rid of dups and sort in place
candidates.uniq!.sort!
puts "Candidates = #{candidates.length}" #
# And the two arrays together leaving only those words
# that appear in both lists
matches = sixLetters & candidates
# Now write the matches to a file
File.open("matches.txt", "w") do |file|
matches.each do |word|
file.puts(word)
end
end
finish = Time.now
puts "Started at #{start}"
puts "Finished at #{finish}"
puts "Total time #{finish.to_i - start.to_i}"
[/tech/ruby] # | | |
||||||||||||||||||||||||||||||||||||||||||||
| Make free, make free your spirit. Sing the song of life. |
|||||||||||||||||||||||||||||||||||||||||||||
| Copyright © 1998 - 2008 Joey Gibson | |||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||