4

I want to execute the following Objective-C code in my Rails application:

CFMutableStringRef inputString = CFStringCreateMutableCopy(kCFAllocatorDefault, 32,     CFSTR("общей"));
CFLocaleRef locale = CFLocaleCreate(kCFAllocatorDefault, CFSTR("ru"));

CFStringTransform(inputString, NULL, kCFStringTransformStripDiacritics, false);
CFStringLowercase(inputString, locale);


NSLog(@"%@", (NSString *)inputString);

CFRelease(locale);
CFRelease(inputString);

It basically outputs a lowercase, diacritics-free version of the input string. I am running on a Snow Leopard server.

How can I do this (without using MacRuby, which seems to be an overkill here)? I've heard of Ruby extensions but can't find any resources in my case.

6
  • This really seems more like a pure Ruby question: "how do I strip diacritics from a string?". Answer: stackoverflow.com/questions/225471/… Commented Nov 17, 2011 at 2:01
  • Unfortunately, it's not that simple... I need to use the native Objective-C functions because I'm dealing with non-latin strings too (Hindi, Mandarin, Russian, etc.). Commented Nov 17, 2011 at 2:14
  • @alste: Somewhat pedantic, but there's no Objective-C in the above. You're using constants and functions from Core Foundation, which is a C library. Anyway, can Rails call out to a binary located on the filesystem? If so, make the above its own little utility, then call out to it as needed, passing the input string as an argument. Note that if you do that, remember not to use NSLog() because it's so noisy. Commented Nov 17, 2011 at 2:34
  • Thanks for your input. I've considered that, but I would have to call the binary thousands of times (when inserting new foreign words into a database, for example - I would want to store their lowercase/diacritics-free version). Is there a more native way to call Core Foundation functions from within Ruby? Commented Nov 17, 2011 at 3:28
  • 1
    Also, Ruby (especially 1.9) can deal with non-Latin characters quite well. You probably don't need Obj-C at all here. Commented Nov 17, 2011 at 14:55

2 Answers 2

1

You can probably do it using ffi, but it'll require entering a bunch of function specs. Tiny test case for calling a Core Foundation function:

require 'ffi'

module CF
  extend FFI::Library
  ffi_lib '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation'
  attach_function :CFAbsoluteTimeGetCurrent, [], :double
end

puts CF.CFAbsoluteTimeGetCurrent
Sign up to request clarification or add additional context in comments.

Comments

0

Instead of creating an app you need to be spawning on and off in a single Rails instance you can write your app using other ways for communication, like named pipes:

http://hints.macworld.com/article.php?story=20041025103920992 http://www.pauldix.net/2009/07/using-named-pipes-in-ruby-for-interprocess-communication.html

Or going the Ruby C extensions way:

http://ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html http://people.apache.org/~rooneg/talks/ruby-extensions/ruby-extensions.html

1 Comment

ruby extensions is the way to go

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.