MotionSupport
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.
Usage
Install with
gem install motion-support
or add to your Gemfile
gem 'motion-support'
API docs
Partial loading
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 => false
Then add a require statement as shown below to your Rakefile
.
all
require 'motion-support'
Loads everything.
callbacks
require 'motion-support/callbacks'
Loads the MotionSupport::Callbacks
module. It allows you to easily add Rails-style callbacks to any class.
concern
require 'motion-support/concern'
Loads the MotionSupport::Concern
module. This simplifies separating classes into modules and managing module dependencies.
inflector
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"
core_ext
require 'motion-support/core_ext'
Loads all the extensions to core classes.
core_ext/array
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' }
core_ext/class
require 'motion-support/core_ext/class'
Loads extensions to class Class
.
class Foo
cattr_accessor :bar
class_attribute :foo
end
core_ext/hash
require '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>
core_ext/integer
require 'motion-support/core_ext/integer'
Loads extensions to class Integer
.
1.ordinalize
=> "1st"
3.ordinalize
=> "3rd"
core_ext/module
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
end
core_ext/numeric
require 'motion-support/core_ext/numeric'
Loads extensions to class Numeric
.
10.kilobytes
=> 10240
2.megabytes
=> 2097152
3.days
=> 3
core_ext/object
require '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)
=> nil
core_ext/range
require 'motion-support/core_ext/range'
Loads extensions to class Range
.
(1..5).overlaps(3..9)
=> true
(1..5).include?(2..3)
=> true
core_ext/string
require '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
=> UIView
core_ext/time
require 'motion-support/core_ext/time'
Loads extensions to class Time
.
1.week.ago
17.days.from_now
Date.yesterday
Time.beginning_of_week
Differences to ActiveSupport
In general:
- All
I18n
stuff was removed. Maybe it will be readded later. - No support for the
TimeWithZone
class (iOS apps don't need advanced time zone support) - No support for the
DateTime
class - All deprecated methods have been removed
- All
YAML
extensions were removed, since RubyMotion doesn't come with YAML support Kernel#silence_warnings
and 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::Unit
were removed - The
ActiveSupport
namespace is calledMotionSupport
Specifically:
Array#third
..Array#fourty_two
were removedArray#to_xml
is missingArray#to_sentence
does not accept a:locale
parameterClass#subclasses
is missing. It depends onObjectSpace.each_object
which is missing in RubyMotionHash#extractable_options?
is missingBigDecimal
conversions were removedTime.current
an alias forTime.now
Date.current
an alias forDate.today
Date#to_time
does not accept a timezone form (:local
,:utc
)Date#xmlschema
is missingString#parameterize
is missing because it needs to transliterate the string, which is dependent on the localeString#constantize
is very slow. Cache the result if you use it.String#to_time
,#to_date
,#to_datetime
are missing because they depend onDate#_parse
- String inquiry methods are missing
- String multibyte methods are missing
String#html_safe
andERB
extensions are not needed in RubyMotionRange#to_s(:db)
was removed- The
rfc822
time format was removed, since it relies on time zone support. - Extensions to
LoadError
andNameError
were removed - The
ThreadSafe
versions ofHash
andArray
are just aliases to the standard classes - In
MotionSupport::Callbacks
it 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.self
is not automatically set. - In
MotionSupport::Callbacks#define_callbacks
, the:terminator
argument must take a block of the formlambda { |result| }
whereresult
is the intermediate result from the callback methods. NumberHelper
and numeric conversions only support phone numbers for now
Things to do / to decide:
- RubyMotion lacks a
Date
class. in_stdlib
there is a stub of a Date class that makes theDate
extensions 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
InfiniteComparable
extensions - Do we need
File#atomic_write
for thread-safe file writing? - Do we need
Kernel#class_eval
(it delegates toclass_eval
on this' singleton class)? - Do we need
Module#qualified_const_defined?
? What is that even for? - Do we need
Module#synchronize
? - Implement
Numeric
conversions, especiallyNumberHelper
- Do we need
Object#with_options
? - Implement
String#to_time
,String#to_date
. In the original ActiveSupport, they make use of theDate#_parse
method (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
Thread
if they make sense. - Do we need the
Configurable
module? - Do we need the
OrderedOptions
class? - Some extensions have to be made available for Cocoa classes (
NSArray
,NSDictionary
etc.), 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.rb
for an example. - Go through documentation and remove or rewrite things not relevant to RubyMotion, especially examples mentioning Rails components
Acknowledgements
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.
Forking
Feel free to fork and submit pull requests!