Thursday, October 11, 2007

Command line for OSX's create Archive functionality

Here's the ditto command for Create Archive functionality of OSX:

ditto -k -c --keepParent --sequesterRsrc Folder_Name Folder_Name.zip

Sunday, October 7, 2007

FormHelpers and validation

1. from_for code: (form_tag_helper.rb):

module FormHelper

def form_for(object_name, object, options={}, &block)
concat('<form ... >')
fields_for(object_name,object,options,&block)
concat('</form>')
end

def fields_for(object_name,object,options={}, &block)
yield builder.new(object_name,object,self,options,block)
end

def text_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_input_field_tag("text", options)
end

end

class FormBuilder
def initialize(object_name, object, template, options, proc)
@object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
end
...
def text_field(method,options)
@template.text_field(@object_name,method,options.merge(:object => @object))
end
...
def fields_for(name, *args, &block)
name = "#{object_name}[#{name}]"
@template.fields_for(name, *args, &block)
end
end




def tag(name, options = nil, open = false, escape = true)
"<#{name}#{tag_options(options, escape) if options}" + (open ? ">" : " />")
end

def tag(name, options)
if object.respond_to?("errors") && object.errors.respond_to?("on")
error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name))
else
super
end
end

def tag_options(options, escape = true)
unless options.blank?
attrs = []
if escape
options.each do |key, value|
next unless value
key = key.to_s
value = BOOLEAN_ATTRIBUTES.include?(key) ? key : escape_once(value)
attrs << %(#{key}="#{value}")
end
else
attrs = options.map { |key, value| %(#{key}="#{value}") }
end
" #{attrs.sort * ' '}" unless attrs.empty?
end
end


Tag helper is:

class InstanceTag
def initialize(object_name, method_name, template_object, local_binding = nil, object = nil)
@object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
@template_object, @local_binding = template_object, local_binding
@object = object
if @object_name.sub!(/\[\]$/,"")
if object ||= @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}") and object.respond_to?(:id_before_type_cast)
@auto_index = object.id_before_type_cast
else
raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to id_before_type_cast: #{object.inspect}"
end
end
end

def to_input_field_tag(field_type, options = {})
options = options.stringify_keys
options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size")
options = DEFAULT_FIELD_OPTIONS.merge(options)
if field_type == "hidden"
options.delete("size")
end
options["type"] = field_type
options["value"] ||= value_before_type_cast(object) unless field_type == "file"
add_default_name_and_id(options)
tag("input", options)
end

end

Saturday, June 2, 2007

Calling attribute setters from module

The question is, what is the output of the following ruby code:


module A
def set_x(y)
x=y
end
end

class B
attr_accessor :x
end

b = B.new
b.x=1
b.set_x(2)
puts b.x


The output is 1, and for first i expected the output to be 2.

A.set_x creates a new local variable x instead of calling the attribute setter, which is proabably a wise decision. Otherwise a module method that intends to use a local variable, might end up using an attribute setter. (If the class which includes the module has one.)

The workaround is to tell the module that you want to access the attribute setter with self.:


module A
def set_x(y)
self.x=y
end
end

Wednesday, April 25, 2007

Howto unload LaunchD deamon from itself

Launchd is cool. It can be used to watchdog your process by setting the OnDemand key to false in the launchd plist. This means that if your program exitst launchd will automatically restart it. But what happens if you want to stop the deamon on purpose?!
First you can unload it with using the following terminal command:

sudo launchctl unload /Libarary/LaunchDaemon/mydaemon.plist


But you can use the following class to programatically use the launchd api for a daemon to unload itself.
Usage is like this:

int main()
{
LaunchD ld;

while(...) {
if (needstop)
ld.Stop();
}
}




class LaunchD
{
public:
LaunchD()
{
startedWithLaunchD = false;
me = 0;
}

~LaunchD()
{
if (me) {
launch_data_free(me);
}
}

bool CheckIn(bool allowRunWithoutLaunchd = true)
{
launch_data_t msg, resp;
msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
if ((resp = launch_msg(msg)) == NULL) {
if (allowRunWithoutLaunchd) {
startedWithLaunchD = false;
return false;
}
syslog(LOG_ERR,"Checkin with launchd failed: %m");
exit(EXIT_FAILURE);
}
launch_data_free(msg);
if (LAUNCH_DATA_ERRNO == launch_data_get_type(resp)) {
errno = launch_data_get_errno(resp);
if (errno == EACCES) {
syslog(LOG_ERR, "Check-in failed. Did you forget to set"
"ServiceIPC == true in your plist?");
} else {
syslog(LOG_ERR, "Check-in failed: %m");
}
exit(EXIT_FAILURE);
}
launch_data_t tmp = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_LABEL);
me = launch_data_copy(tmp);
startedWithLaunchD = true;
if (tmp) {
syslog(LOG_ERR, "My job label:%s\n",launch_data_get_string(tmp));
}
return true;
}

bool Stop()
{
if (startedWithLaunchD) {
launch_data_t resp;
launch_data_t msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
if (! launch_data_dict_insert(msg,me,LAUNCH_KEY_REMOVEJOB)) {
syslog(LOG_ERR, "launch_data_dict_insert failed!\n");
return false;
}
if (! launch_data_dict_insert(msg,me,LAUNCH_KEY_STOPJOB)) {
syslog(LOG_ERR, "launch_data_dict_insert failed!\n");
return false;
}
if ((resp = launch_msg(msg)) == NULL) {
syslog(LOG_ERR, "launch_msg LAUNCH_KEY_STOPJOB failed!\n");
return false;
}
if (LAUNCH_DATA_ERRNO == launch_data_get_type(resp)) {
errno = launch_data_get_errno(resp);
if (errno == EACCES) {
syslog(LOG_ERR, "Stop request failed EACCESS!");
} else {
syslog(LOG_ERR, "Check-in failed: %m");
}
exit(EXIT_FAILURE);
}
launch_data_free(msg);
}
return true;
}
private:
bool startedWithLaunchD;
launch_data_t me;
};

Tuesday, January 9, 2007

IsItCarbonWindow or IsItCocoaWindow?!

I've found the following implementation:


@class NSCarbonWindow;

bool IsItACocoaWindow (WindowRef window)
{
NSWindow* cocoaWindow = [[NSWindow alloc] initWithWindowRef:window];
BOOL carbon = [[cocoaWindow class]isSubclassOfClass:[NSCarbonWindow class]];
[cocoaWindow release];
return !carbon;
}


bool IsItACarbonWindow (WindowRef window)
{
/* This one is a pure carbon function but it's a bit fragile, as for example in Leopard it actually returns: com.apple.hitoolbox.window.viewadapter */
CFStringRef classid = HIObjectCopyClassID ((HIObjectRef) window);
bool cocoa = (CFStringCompare (CFSTR ("com.apple.hitoolbox.window.external"), classid, 0) == kCFCompareEqualTo) ||
(CFStringCompare (CFSTR ("com.apple.hitoolbox.window. viewadapter"), classid, 0) == kCFCompareEqualTo);
CFRelease (classid);
return !cocoa;
}



It's also interesting to note that this can work because in case of the CocoaWindow the initWithWindowRef method will return the original window object for Cocoa objects. That is:


window == [[NSWindow alloc] initWithWindowRef: [window windowRef]];