A Simple Ruby Example

 

Overview

The following Ruby service script will convert any selected text into uppercase. This is a trivial example in that there is no GUI interaction, does not utilize any additional Ruby libraries, nor does it deal with multiple pasteboard types. It does, however, illustrate the basic points to consider when implementing services with Ruby.

 

A Simple Example: Convert to Uppercase

The following code listing shows a complete Bellhop service script written in the Ruby language. You can try this yourself by simply creating a Bellhop document, adding a new Ruby service, and then pasting the following code directly into the editor window. Then all you have to do is activate the service using the Settings panel, and then you can invoke it from any services-aware application.

# Sample Ruby service to make the selection string all uppercase. This # service might be labeled "Make Uppercase String" in the Services menu. # The aPasteboard argument identifies the unique pasteboard name # that is reserved for the current service transaction. You will # use this name as the argument to the various methods that get # and set data from the pasteboard. def runService (aPasteboard) # Read pasteboard string string = Pasteboard.readString(aPasteboard, NSStringPboardType) # Now do our stuff string.upcase! # Write result back to pasteboard Pasteboard.declareTypes(aPasteboard, [NSStringPboardType]) Pasteboard.writeString(aPasteboard, NSStringPboardType, string) end

Listing 1: Sample Ruby service

If you are familiar with the concepts and implementation details regarding system services in Mac OS X, the above script should be straightforward. If not, you can refer to the Apple developer documentation covering System Services and the More Info section of this document.

Looking at Listing 1, the first non-comment line is

def runService(aPasteboard)

This is the entry to your service. Almost all of your runService() functions will follow a similar pattern: read pasteboard data, operate on it, and write modified pasteboard data back. The only argument to this function, aPasteboard, is the particular pasteboard that is used for this service transaction. Each service transaction is assigned a unique service pasteboard.

The following lines read the selection from the service pasteboard:

# Read pasteboard string string = Pasteboard.readString(aPasteboard, NSStringPboardType)

This line uses the Bellhop Pasteboard extension for Ruby to get a string from the pasteboard. Notice the use of the NSStringPboardType constant to specify string type data. This is one of the global pasteboard type constants that is made available to all Bellhop Ruby scripts, and mimics the same symbolic constant as defined in the Cocoa frameworks.

Next we manipulate the pasteboard data to modify it:

# Now do our stuff string.upcase!

This line uses the destructive version of the upcase method defined in the Ruby String class, which alters the contents of a string by converting all of its characters to uppercase. This is the meat of our service.

Finally, we must write the modified data back to the pasteboard so that it is made available to the requesting application:

# Write result back to pasteboard Pasteboard.declareTypes(aPasteboard, [NSStringPboardType]) Pasteboard.writeString(aPasteboard, NSStringPboardType, string)

These lines first inform aPasteboard (our unique service pasteboard) that we are about to provide it with string data. Then we actually write the modified string to aPasteboard. Again, notice that we are using the custom Bellhop Pasteboard module to deal with the Mac OS X pasteboard.

And finally, to conform to valid Ruby syntax, we close our function definition:

end

It is worth pointing out that we did not have to explicitly import any Bellhop custom modules, and we are using constants that mimic those defined in the Cocoa frameworks.

That's all there is to it! When a user invokes our "Make Uppercase String" service from the Services menu (e.g. from the TextEdit application), the operating system will automatically forward the request to Bellhop, which will in turn invoke the appropriate script's runService() function. All of your services will follow a similar pattern.