This is a port of the parts of ActiveSupport that make sense for RubyMotion.
To see what's there, generate the documentation with the rdoc command from the repository root, or look into the lib folder. Almost everything is tested.
Install with
gem install motion-support
or add to your Gemfile
gem 'motion-support'It is also possible to only use parts of this library. To do so, change your Gemfile so that it reads:
gem 'motion-support', :require => falseThen add a require statement as shown below to your Rakefile.
require 'motion-support'Loads everything.
require 'motion-support/callbacks'Loads the MotionSupport::Callbacks module. It allows you to easily add Rails-style callbacks to any class.
require 'motion-support/concern'Loads the MotionSupport::Concern module. This simplifies separating classes into modules and managing module dependencies.
require 'motion-support/inflector'Loads the Inflector module and extensions to the String class. See the "Inflector" app in the examples/ folder for what the inflector can do.
Example usage include:
"app_delegate".camelize
=> "AppDelegate"
"HomeController".constantize
=> HomeController
"thing".pluralize
=> "things"
"mice".singularize
=> "mouse"require 'motion-support/core_ext'Loads all the extensions to core classes.
require 'motion-support/core_ext/array'Loads extensions to class Array. Example usage include
%w( a b c d ).from(2)
=> ["c", "d"]
['one', 'two', 'three'].to_sentence
=> "one, two, and three"
[1, 2, 3, 4].in_groups_of(2)
=> [[1, 2], [3, 4]]Extract options hash from variant args array
args = ['hello', 'world', { :foo => 'bar' }]
args.extract_options!
=> { :foo => 'bar' }require 'motion-support/core_ext/class'Loads extensions to class Class.
class Foo
cattr_accessor :bar
class_attribute :foo
endrequire 'motion-support/core_ext/hash'Loads extensions to class Hash, including class HashWithIndifferentAccess.
{ 'foo' => 'bar', 'baz' => 'bam' }.symbolize_keys
=> { :foo => 'bar', :baz => 'bam' }
{ 'foo' => 'bar', 'baz' => 'bam' }.except('foo')
=> { 'baz' => 'bam' }
{ 'foo' => 'bar', 'baz' => 'bam' }.with_indifferent_access
=> #<HashWithIndifferentAccess>require 'motion-support/core_ext/integer'Loads extensions to class Integer.
1.ordinalize
=> "1st"
3.ordinalize
=> "3rd"require 'motion-support/core_ext/module'Loads extensions to class Module.
module Mod
mattr_accessor :foo, :bar
attr_internal :baz
delegate :boo, :to => :foo
remove_method :baz
endrequire 'motion-support/core_ext/numeric'Loads extensions to class Numeric.
10.kilobytes
=> 10240
2.megabytes
=> 2097152
3.days
=> 3require 'motion-support/core_ext/object'Loads extensions to class Object.
nil.blank?
=> true
Object.new.blank?
=> false
{ "hello" => "world", "foo" => "bar" }.to_query
=> "hello=world&foo=bar"
1.duplicable?
=> false
1.try(:to_s)
=> "1"
nil.try(:to_s)
=> nilrequire 'motion-support/core_ext/range'Loads extensions to class Range.
(1..5).overlaps(3..9)
=> true
(1..5).include?(2..3)
=> truerequire 'motion-support/core_ext/string'Loads extensions to class String.
"ruby_motion".camelize
=> "RubyMotion"
"User".pluralize
=> "Users"
"mice".singularize
=> "mouse"
"Foo::Bar".underscore
=> "foo/bar"
"AppDelegate".underscore
=> "app_delegate"
"UIView".constantize
=> UIViewrequire 'motion-support/core_ext/time'Loads extensions to class Time.
1.week.ago
17.days.from_now
Date.yesterday
Time.beginning_of_weekIn general:
- All
I18nstuff was removed. Maybe it will be readded later. - No support for the
TimeWithZoneclass (iOS apps don't need advanced time zone support) - No support for the
DateTimeclass - All deprecated methods have been removed
- All
YAMLextensions were removed, since RubyMotion doesn't come with YAML support Kernel#silence_warningsand stream manipulation methods were removed- Multibyte string handling methods have been removed
- All Rails-specific stuff was removed
- The dependency resolution code was removed. So was the dynamic code reloading code
- All marshalling code was removed
- All logging code was removed
- All extensions to
Test::Unitwere removed - The
ActiveSupportnamespace is calledMotionSupport
Specifically:
Array#third..Array#fourty_twowere removedArray#to_xmlis missingArray#to_sentencedoes not accept a:localeparameterClass#subclassesis missing. It depends onObjectSpace.each_objectwhich is missing in RubyMotionHash#extractable_options?is missingBigDecimalconversions were removedTime.currentan alias forTime.nowDate.currentan alias forDate.todayDate#to_timedoes not accept a timezone form (:local,:utc)Date#xmlschemais missingString#parameterizeis missing because it needs to transliterate the string, which is dependent on the localeString#constantizeis very slow. Cache the result if you use it.String#to_time,#to_date,#to_datetimeare missing because they depend onDate#_parse- String inquiry methods are missing
- String multibyte methods are missing
String#html_safeandERBextensions are not needed in RubyMotionRange#to_s(:db)was removed- The
rfc822time format was removed, since it relies on time zone support. - Extensions to
LoadErrorandNameErrorwere removed - The
ThreadSafeversions ofHashandArrayare just aliases to the standard classes - In
MotionSupport::Callbacksit is not possible to give a string containing Ruby code as a conditions via:if, since RubyMotion doesn't supporteval. - In
MotionSupport::Callbacks, if a proc is given as a condition to:if, the block must take the class instance as a parameter.selfis not automatically set. - In
MotionSupport::Callbacks#define_callbacks, the:terminatorargument must take a block of the formlambda { |result| }whereresultis the intermediate result from the callback methods. NumberHelperand numeric conversions only support phone numbers for now
Things to do / to decide:
- RubyMotion lacks a
Dateclass. in_stdlibthere is a stub of a Date class that makes theDateextensions work. This stub needs to be completed. - Implement
Object#to_xml - Implement
Hash#from_xml - Do we need
Hash#extractable_options?? - Do we need
Class#superclass_delegating_accessor? - Implement all
InfiniteComparableextensions - Do we need
File#atomic_writefor thread-safe file writing? - Do we need
Kernel#class_eval(it delegates toclass_evalon this' singleton class)? - Do we need
Module#qualified_const_defined?? What is that even for? - Do we need
Module#synchronize? - Implement
Numericconversions, especiallyNumberHelper - Do we need
Object#with_options? - Implement
String#to_time,String#to_date. In the original ActiveSupport, they make use of theDate#_parsemethod (which seems like it's supposed to be private). Here, they should be implemented on top of Cocoa APIs - Do we need
String#parameterize? If so, we need to find a way to transliterate UTF-8 characters. - Do we need the
StringInquirer? It allows things likeRails.env.development?instead ofRails.env == 'development' - Do we need multibyte string handling extensions? AFAIK, all strings in RubyMotion are UTF-8. Is that true?
- Do we need
Struct#to_h? - Implement extensions to class
Threadif they make sense. - Do we need the
Configurablemodule? - Do we need the
OrderedOptionsclass? - Some extensions have to be made available for Cocoa classes (
NSArray,NSDictionaryetc.), since we want to effectively handle return values from Objective-C methods (they return Cocoa classes). The way to do this is to write a conversion method from Cocoa class to Ruby class and delegate the extension methods in the Cocoa class to the conversion method. Seemotion/core_ext/ns_string.rbfor an example. - Go through documentation and remove or rewrite things not relevant to RubyMotion, especially examples mentioning Rails components
ActiveSupport was originally written as part of Ruby on Rails by David Heinemeier Hansson. Over the years, countless contributors made many additions. They made this library possible.
Feel free to fork and submit pull requests!