ar_mailer 1.5.0

Eric Hodel | Fri, 16 Oct 2009 00:02:05 GMT

ar_mailer is a two-phase delivery agent for ActionMailer. Even delivering email to the local machine may take too long when you have to send hundreds of messages. ar_mailer allows you to store messages into the database for later delivery by a separate process, ar_sendmail.

Changes

  • Added --pid-file option. See --help for details.
  • Minor improvements to --help, argument error output

Posted in , ,  | 2 comments

dnssd 1.3.1

Eric Hodel | Wed, 14 Oct 2009 03:05:58 GMT

dnssd version 1.3.1 has been released!

DNS Service Discovery (aka Bonjour, MDNS) API for Ruby. Implements browsing, resolving, registration and domain enumeration. Supports avahi's DNSSD compatibility layer for avahi 0.6.25 or newer.

Changes

  • 1 bug fix
    • Fix regexp for parsing the fullname. Patch by James Sadler.

Posted in ,  | no comments

imap_to_rss 1.1

Eric Hodel | Tue, 01 Sep 2009 22:47:00 GMT

imap_to_rss version 1.1 has been released!

IMAPToRSS turns messages on an IMAP server into RSS entries when the match a handler. Included handlers work for email from Amazon, HSBC and UPS. IMAPToRSS automatically loads handlers for any other mail.

Changes:

  • 1 major enhancement
    • Added iTunes handler
  • 1 bug fix
    • Fixed various bugs in the Amazon handler

Posted in ,  | no comments

dnssd 1.3

Eric Hodel | Wed, 19 Aug 2009 04:31:00 GMT

DNS Service Discovery (aka Bonjour, MDNS) API for Ruby. Implements browsing, resolving, registration and domain enumeration. Supports avahi’s DNSSD compatibility layer for avahi 0.6.25 or newer.

Changes

  • 4 major enhancements
    • Added DNSSD::Service.get_property
    • Added DNSSD::Service#getaddrinfo
    • Added DNSSD::Service#add_record
    • Added DNSSD::Service#query_record
  • 5 minor enhancements
    • DNSSD::Reply#connect now uses DNSSD::Service#getaddrinfo (faster)
    • DNSSD::Service#register behaves properly when blockless
    • Broke up DNSSD::Reply into specific subclasses
    • Added sample/query_record.rb
    • sample/*.rb work with each other now for clarity of implementation
  • 2 bug fixes
    • Fix hierarchical domains like \.mac\.name.members.mac.com.
    • Fix compilation against avahi 0.6.25

Posted in ,  | no comments

On Ruby C Extensions

Eric Hodel | Tue, 18 Aug 2009 02:07:40 GMT

I’m not a great C coder, but I have implemented, cleaned up and read a few C extensions for Ruby and I’ve got some tips for writing C extensions

C is Bad

The C itself is your biggest enemy when writing C extensions. The more you write the harder it is for you to maintain and the harder it will be for anyone else to improve or fix your code in the future. The closer your C extension code is to the library’s API the better you can use Ruby to glue all the pieces together into a friendly interface.

Ruby is Good

With less C code and more Ruby code you end up a library that’s easier to refactor, adapt and extend. Generic data manipulation, simple math, convenience functions, etc. are all easier to write, test and debug when written in Ruby. There’s no need to recompile between changes, worry about compiler warnings, or fix type errors.

If you’re returning results from an operation, do as much of the work in Ruby as possible. If there are objects that can be created in Ruby create them in Ruby. If you get a struct sockaddr, unpack it on the Ruby side rather than calling the Socket methods from C using rb_funcall. If you’ve got an abstract representation of a flag bitfield, create the object on the Ruby side rather than calling rb_class_new_instance.

Check for what you need

mkmf.rb has loads of functions (dir_config, have_library, have_macro, have_func, have_type, have_struct_member, etc.) for determining whether or not you have everything you need to build your extension. When using these functions be sure to check the result and fail when what you need is missing.

Keep Up-to-date on the Ruby/C API

There’s tons of functions and macros for doing most of you need already built-in to Ruby. README.EXT has the overview, but there’s also ruby.h and intern.h which give you a list of functions you can use.

Use the friendly macros RSTRING_LEN, RSTRING_PTR and friends when playing with String, Array, etc. Use rb_define_alloc_func() with Data_Wrap_Struct(). Use RTEST and NIL_P for checking ruby results. Convert numbers with NUM2ULONG or NUM2INT, etc.

Play Nice with Threads

If you’re performing a blocking IO operation use rb_thread_wait_fd, rb_thread_fd_writable, etc. to keep other threads running. rb_thread_wait_for can be used for polling.

Don’t Repeat Yourself

While it is safe to repeatedly call rb_intern() if you have to invoke rb_funcall or rb_iv_set, it’s easier and prettier to use a static variable set from your Init function. Same for looking up classes using rb_path2class() or rb_define_class_under().

C is bad

It’s worth repeating. Writing C code is hard. Refactoring C code is hard. Debugging C code is hard. Do as little as possible in C and you’ll thank yourself down the road.

Posted in  | 2 comments

dnssd 1.2

Eric Hodel | Thu, 13 Aug 2009 05:45:00 GMT

DNS Service Discovery (aka Bonjour, MDNS) API for Ruby. Implements browsing, resolving, registration and domain enumeration.

Changes:

  • 4 major enhancements
    • DNSSD::Service is now directly instantiable
    • DNSSD.announce which registers a server socket you’ve created
    • DNSSD::Reply.connect which connects to a browsed service
    • Fix asynchronous service shutdown crash
  • 8 minor enhancements
    • DNSSD.resolve now optionally accepts a DNSSD::Reply from DNSSD.browse
    • Use rb_thread_wait_fd instead of custom rb_thread_select code
    • DNSSD::Reply#protocol and DNSSD::Reply#service_name
    • Added missing error classes
    • Added missing InterfaceUnicast constant
    • Improved Documentation
    • Use C constants in ext/dnssd/errors.c
    • Reduced C code in ext/dnssd/service.c for greater control. See DNSSD::Service
  • 4 bug fixes
    • Don’t invoke block on callback if none was provided
    • Remove ext/dnssd/dns_sd.h so the correct header is used
    • DNSSD::NoMemoryError is now raised instead of NoMemError
    • DNSSD::ReferenceUsedError is now correctly named DNSSD::RefusedError

Posted in  | no comments

vi bindings for irb on OS X

Eric Hodel | Tue, 11 Aug 2009 20:56:22 GMT

OS X uses editline(3) instead of readline(3) so ~/.inputrc doesn’t do anything for irb or other tools using readline via the editline wrapper.

Instead, use ~/.editrc:

bind -v
bind \\t rl_complete

Which gives you vi bindings in irb.

Update

Now with tab completion thanks to Curt Sampson from an ancient netbsd-users email!

Posted in ,  | no comments

Converting from REXML to Nokogiri

Eric Hodel | Thu, 18 Jun 2009 01:02:02 GMT

Nokogiri is pretty darn cool, certainly far cooler than REXML. I switched UPnP to Nokogiri, and here’s a handy guide.

require 'rexml/document'

Becomes

require 'nokogiri'
REXML::Document.new

Becomes

Nokogiri::XML

Both accept String or IO objects

my_element.element['element/path']

Becomes

my_element.at 'element > path'

You can use CSS in #at

my_element.each_element 'element/path' do |sub_element|

Becomes

my_element.xpath('./xmlns:element/xmlns:path').each do |sub_element|

”.” is used to select sub-elements of this one

See also Nokogiri’s Node documentation.

Posted in ,  | no comments

UPnP 1.2.0

Eric Hodel | Wed, 17 Jun 2009 00:06:07 GMT

An implementation of the UPnP protocol

Changes

  • 2 minor enhancements
    • Workaround for missing socket constants on Windows. Reported by Yuri.
    • upnp_discover now shows action argument and return value names.
  • 4 bug fixes
    • Method name must not include entire URI. Reported by Ian Macdonald.
    • Step in allowedValueRange is optional. Reported by Ian Macdonald.
    • upnp_listen works with all notification types. Reported by Ian Macdonald.
    • upnp_discover now warns when a device failed to instantiate. Reported by Ian Macdonald.

Posted in ,  | no comments

A Project Naming Recommendation

Eric Hodel | Wed, 20 May 2009 23:08:02 GMT

I’ve gone through many different styles of project names, but I think I’ve finally found a naming scheme I like.

In the past, I’ve used class names with uppercase letters, dashed names and underscored names, and I think the underscores are the best for projects I’m packaging in ruby.

Rails solidified the convention of mapping CamelCase class names to underscored file names (class IMAPProcesor is defined in imap_processor.rb). Using underscored gem names makes it easy for people to figure out what file to require (same as the project name) or what class name to look for in ri.

If I have a plugin gem or an extension I’ll tack on the sub-project’s name with a dash. If I wanted to add a new handler for imap_to_rss for Chase bank email, the gem would be named imap_to_rss-chase.

This makes it easy to find in gem list -p and it conveniently namespaces the extension. It also would look nice with gems from github which break up author and project with a dash (drbrain-imap_to_rss-chase, if I used github). As an added bonus, when double-clicking any underscored part OS X only highlights a part of the name making cut-and-paste a little more convenient for picking apart gem names.

Currently almost 95% of gem names start with lowercase letters, 6% contain uppercase letters anywhere in the name, a little over 20% use dashes, 16% use underscore. Sixteen use both underscores and dashes (my favorite name being what_does_this_error_mean-merb).

Posted in ,  | 2 comments

Older posts: 1 2 3 ... 11