droiuby 0.2.6 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/drby +6 -2
- data/lib/droiuby/scripts/project.rb +6 -5
- data/lib/droiuby/support/object/acts_like.rb +10 -0
- data/lib/droiuby/support/object/blank.rb +105 -0
- data/lib/droiuby/support/object/deep_dup.rb +46 -0
- data/lib/droiuby/support/object/duplicable.rb +90 -0
- data/lib/droiuby/support/object/inclusion.rb +24 -0
- data/lib/droiuby/support/object/instance_variables.rb +28 -0
- data/lib/droiuby/support/object/to_param.rb +58 -0
- data/lib/droiuby/support/object/to_query.rb +27 -0
- data/lib/droiuby/support/object/try.rb +78 -0
- data/lib/droiuby/support/object.rb +10 -10
- data/lib/droiuby/support/string/access.rb +104 -0
- data/lib/droiuby/support/string/behavior.rb +6 -0
- data/lib/droiuby/support/string/droiuby.rb +60 -0
- data/lib/droiuby/support/string/exclude.rb +11 -0
- data/lib/droiuby/support/string/filters.rb +55 -0
- data/lib/droiuby/support/string/indent.rb +43 -0
- data/lib/droiuby/support/string/starts_ends_with.rb +4 -0
- data/lib/droiuby/support/string.rb +7 -60
- metadata +18 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c99a0427b7d58933183c619cfa0f72c8865cc96e
|
4
|
+
data.tar.gz: 207329828f330d981798948cabb1f116fd235fde
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5085ed07cf25a2ad536790c0c373d313126908f626400c33c5e142e81755667805b6e726c7a281f3f3e73585e385fd9cc86343885b6aecef46d1706e28429e26
|
7
|
+
data.tar.gz: 4bb8b45851683725c3c279e8ed3464d2e3295ac42030588fe9016424142aa7733c8ff2aabea1d15317f941c73e25f42df085cba02243bae0789b6aeab1453856
|
data/bin/drby
CHANGED
@@ -8,6 +8,7 @@ require "readline"
|
|
8
8
|
|
9
9
|
$droiuby_host = ENV['DROIUBY_HOST'] || '10.0.2.2'
|
10
10
|
$device_ip = ENV['DROIUBY_DEVICE'] || nil
|
11
|
+
$app_name = nil
|
11
12
|
|
12
13
|
options = OptionParser.new do |o|
|
13
14
|
o.banner =
|
@@ -19,13 +20,15 @@ options = OptionParser.new do |o|
|
|
19
20
|
drby live [PROJECT_NAME] [options] # runs a web instance of the app and tells Droiuby to load it.
|
20
21
|
drby new PROJECT_NAME [options] # Create a new project
|
21
22
|
drby pack [PROJECT_NAME] [options] # zips and packages an app
|
22
|
-
drby standalone [PROJECT_NAME] --package
|
23
|
+
drby standalone [PROJECT_NAME] --package JAVA_PACKAGE # creates a standalone android project for the current app
|
24
|
+
[--name APP_NAME]
|
23
25
|
drby reload # uploads and then reload the current app
|
24
26
|
drby switch INSTANCE_NAME [options] # Switch to the specified instance
|
25
27
|
drby bundle # unzips all gems in vendor/cache for deployment to droiuby\n"
|
26
28
|
|
27
29
|
o.separator ""
|
28
30
|
o.separator "options:"
|
31
|
+
o.on('-n','--name app_name','The name of the app that appears in the launcher') {|b| $app_name =b }
|
29
32
|
o.on('-p','--package java_package','The java package name to use') {|b| $java_package = b}
|
30
33
|
o.on('-h','--host HOST_IP','The IP Address of the host computer (for droiuby live mode)') { |b| $droiuby_host = b }
|
31
34
|
o.on('-d','--device DEVICE_IP','The IP Address of the Android Device') { |b| $device_ip = b }
|
@@ -113,7 +116,8 @@ case command
|
|
113
116
|
puts '--package [JAVA_PACKAGE] is required.'
|
114
117
|
exit(1)
|
115
118
|
end
|
116
|
-
project.standalone(project_name, $java_package, ''
|
119
|
+
project.standalone(project_name, $java_package, $app_name.nil? ? 'HelloWorld'
|
120
|
+
: $app_name,'')
|
117
121
|
when 'switch'
|
118
122
|
instance_name = nil
|
119
123
|
unless ARGV[1].blank?
|
@@ -5,8 +5,8 @@ require 'zip'
|
|
5
5
|
require 'thor'
|
6
6
|
require "uri"
|
7
7
|
require 'cgi'
|
8
|
-
require '
|
9
|
-
require '
|
8
|
+
require 'droiuby/support/object'
|
9
|
+
require 'droiuby/support/string'
|
10
10
|
|
11
11
|
class Project < Thor
|
12
12
|
|
@@ -119,7 +119,7 @@ class Project < Thor
|
|
119
119
|
end
|
120
120
|
|
121
121
|
desc "standalone NAME [PACKAGE_NAME]", "create an android project for this app with the specified java package name"
|
122
|
-
def standalone(name, package_name, output_dir = 'projects')
|
122
|
+
def standalone(name, package_name, title = 'HelloWorld', output_dir = 'projects')
|
123
123
|
|
124
124
|
if output_dir.blank?
|
125
125
|
output_dir = Dir.pwd
|
@@ -150,7 +150,7 @@ class Project < Thor
|
|
150
150
|
archive_name = File.basename(dest_folder.sub!(%r[/$],'')) if archive_name.nil?
|
151
151
|
|
152
152
|
init = Init.new
|
153
|
-
init.init(package_name, "#{archive_name}.zip")
|
153
|
+
init.init(package_name, "#{archive_name}.zip", title)
|
154
154
|
Dir.chdir dest_folder
|
155
155
|
bundle
|
156
156
|
package(name, '', "true")
|
@@ -366,7 +366,8 @@ class Project < Thor
|
|
366
366
|
FileUtils.rm archive, :force=>true
|
367
367
|
|
368
368
|
Zip::File.open(archive, Zip::File::CREATE) do |zipfile|
|
369
|
-
Dir.glob("**{,/*/**}/*.*").reject{ |f| f==archive ||
|
369
|
+
Dir.glob("**{,/*/**}/*.*").reject{ |f| f==archive ||
|
370
|
+
f.match(/^build/) || f.match(/^project/) }.uniq.each do |file|
|
370
371
|
say_status 'adding', file
|
371
372
|
begin
|
372
373
|
zipfile.add(file, file)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Object
|
2
|
+
# A duck-type assistant method. For example, Active Support extends Date
|
3
|
+
# to define an <tt>acts_like_date?</tt> method, and extends Time to define
|
4
|
+
# <tt>acts_like_time?</tt>. As a result, we can do <tt>x.acts_like?(:time)</tt> and
|
5
|
+
# <tt>x.acts_like?(:date)</tt> to do duck-type-safe comparisons, since classes that
|
6
|
+
# we want to act like Time simply need to define an <tt>acts_like_time?</tt> method.
|
7
|
+
def acts_like?(duck)
|
8
|
+
respond_to? :"acts_like_#{duck}?"
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# An object is blank if it's false, empty, or a whitespace string.
|
5
|
+
# For example, '', ' ', +nil+, [], and {} are all blank.
|
6
|
+
#
|
7
|
+
# This simplifies:
|
8
|
+
#
|
9
|
+
# if address.nil? || address.empty?
|
10
|
+
#
|
11
|
+
# ...to:
|
12
|
+
#
|
13
|
+
# if address.blank?
|
14
|
+
def blank?
|
15
|
+
respond_to?(:empty?) ? empty? : !self
|
16
|
+
end
|
17
|
+
|
18
|
+
# An object is present if it's not <tt>blank?</tt>.
|
19
|
+
def present?
|
20
|
+
!blank?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns object if it's <tt>present?</tt> otherwise returns +nil+.
|
24
|
+
# <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
|
25
|
+
#
|
26
|
+
# This is handy for any representation of objects where blank is the same
|
27
|
+
# as not present at all. For example, this simplifies a common check for
|
28
|
+
# HTTP POST/query parameters:
|
29
|
+
#
|
30
|
+
# state = params[:state] if params[:state].present?
|
31
|
+
# country = params[:country] if params[:country].present?
|
32
|
+
# region = state || country || 'US'
|
33
|
+
#
|
34
|
+
# ...becomes:
|
35
|
+
#
|
36
|
+
# region = params[:state].presence || params[:country].presence || 'US'
|
37
|
+
def presence
|
38
|
+
self if present?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class NilClass
|
43
|
+
# +nil+ is blank:
|
44
|
+
#
|
45
|
+
# nil.blank? # => true
|
46
|
+
def blank?
|
47
|
+
true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class FalseClass
|
52
|
+
# +false+ is blank:
|
53
|
+
#
|
54
|
+
# false.blank? # => true
|
55
|
+
def blank?
|
56
|
+
true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class TrueClass
|
61
|
+
# +true+ is not blank:
|
62
|
+
#
|
63
|
+
# true.blank? # => false
|
64
|
+
def blank?
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Array
|
70
|
+
# An array is blank if it's empty:
|
71
|
+
#
|
72
|
+
# [].blank? # => true
|
73
|
+
# [1,2,3].blank? # => false
|
74
|
+
alias_method :blank?, :empty?
|
75
|
+
end
|
76
|
+
|
77
|
+
class Hash
|
78
|
+
# A hash is blank if it's empty:
|
79
|
+
#
|
80
|
+
# {}.blank? # => true
|
81
|
+
# { key: 'value' }.blank? # => false
|
82
|
+
alias_method :blank?, :empty?
|
83
|
+
end
|
84
|
+
|
85
|
+
class String
|
86
|
+
# A string is blank if it's empty or contains whitespaces only:
|
87
|
+
#
|
88
|
+
# ''.blank? # => true
|
89
|
+
# ' '.blank? # => true
|
90
|
+
# ' '.blank? # => true
|
91
|
+
# ' something here '.blank? # => false
|
92
|
+
def blank?
|
93
|
+
self !~ /[^[:space:]]/
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class Numeric #:nodoc:
|
98
|
+
# No number is blank:
|
99
|
+
#
|
100
|
+
# 1.blank? # => false
|
101
|
+
# 0.blank? # => false
|
102
|
+
def blank?
|
103
|
+
false
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'droiuby/support/object/duplicable'
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# Returns a deep copy of object if it's duplicable. If it's
|
5
|
+
# not duplicable, returns +self+.
|
6
|
+
#
|
7
|
+
# object = Object.new
|
8
|
+
# dup = object.deep_dup
|
9
|
+
# dup.instance_variable_set(:@a, 1)
|
10
|
+
#
|
11
|
+
# object.instance_variable_defined?(:@a) #=> false
|
12
|
+
# dup.instance_variable_defined?(:@a) #=> true
|
13
|
+
def deep_dup
|
14
|
+
duplicable? ? dup : self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Array
|
19
|
+
# Returns a deep copy of array.
|
20
|
+
#
|
21
|
+
# array = [1, [2, 3]]
|
22
|
+
# dup = array.deep_dup
|
23
|
+
# dup[1][2] = 4
|
24
|
+
#
|
25
|
+
# array[1][2] #=> nil
|
26
|
+
# dup[1][2] #=> 4
|
27
|
+
def deep_dup
|
28
|
+
map { |it| it.deep_dup }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Hash
|
33
|
+
# Returns a deep copy of hash.
|
34
|
+
#
|
35
|
+
# hash = { a: { b: 'b' } }
|
36
|
+
# dup = hash.deep_dup
|
37
|
+
# dup[:a][:c] = 'c'
|
38
|
+
#
|
39
|
+
# hash[:a][:c] #=> nil
|
40
|
+
# dup[:a][:c] #=> "c"
|
41
|
+
def deep_dup
|
42
|
+
each_with_object(dup) do |(key, value), hash|
|
43
|
+
hash[key.deep_dup] = value.deep_dup
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
#--
|
2
|
+
# Most objects are cloneable, but not all. For example you can't dup +nil+:
|
3
|
+
#
|
4
|
+
# nil.dup # => TypeError: can't dup NilClass
|
5
|
+
#
|
6
|
+
# Classes may signal their instances are not duplicable removing +dup+/+clone+
|
7
|
+
# or raising exceptions from them. So, to dup an arbitrary object you normally
|
8
|
+
# use an optimistic approach and are ready to catch an exception, say:
|
9
|
+
#
|
10
|
+
# arbitrary_object.dup rescue object
|
11
|
+
#
|
12
|
+
# Rails dups objects in a few critical spots where they are not that arbitrary.
|
13
|
+
# That rescue is very expensive (like 40 times slower than a predicate), and it
|
14
|
+
# is often triggered.
|
15
|
+
#
|
16
|
+
# That's why we hardcode the following cases and check duplicable? instead of
|
17
|
+
# using that rescue idiom.
|
18
|
+
#++
|
19
|
+
class Object
|
20
|
+
# Can you safely dup this object?
|
21
|
+
#
|
22
|
+
# False for +nil+, +false+, +true+, symbol, and number objects;
|
23
|
+
# true otherwise.
|
24
|
+
def duplicable?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class NilClass
|
30
|
+
# +nil+ is not duplicable:
|
31
|
+
#
|
32
|
+
# nil.duplicable? # => false
|
33
|
+
# nil.dup # => TypeError: can't dup NilClass
|
34
|
+
def duplicable?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class FalseClass
|
40
|
+
# +false+ is not duplicable:
|
41
|
+
#
|
42
|
+
# false.duplicable? # => false
|
43
|
+
# false.dup # => TypeError: can't dup FalseClass
|
44
|
+
def duplicable?
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class TrueClass
|
50
|
+
# +true+ is not duplicable:
|
51
|
+
#
|
52
|
+
# true.duplicable? # => false
|
53
|
+
# true.dup # => TypeError: can't dup TrueClass
|
54
|
+
def duplicable?
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Symbol
|
60
|
+
# Symbols are not duplicable:
|
61
|
+
#
|
62
|
+
# :my_symbol.duplicable? # => false
|
63
|
+
# :my_symbol.dup # => TypeError: can't dup Symbol
|
64
|
+
def duplicable?
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Numeric
|
70
|
+
# Numbers are not duplicable:
|
71
|
+
#
|
72
|
+
# 3.duplicable? # => false
|
73
|
+
# 3.dup # => TypeError: can't dup Fixnum
|
74
|
+
def duplicable?
|
75
|
+
false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
require 'bigdecimal'
|
80
|
+
class BigDecimal
|
81
|
+
begin
|
82
|
+
BigDecimal.new('4.56').dup
|
83
|
+
|
84
|
+
def duplicable?
|
85
|
+
true
|
86
|
+
end
|
87
|
+
rescue TypeError
|
88
|
+
# can't dup, so use superclass implementation
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Object
|
2
|
+
# Returns true if this object is included in the argument. Argument must be
|
3
|
+
# any object which responds to +#include?+. Usage:
|
4
|
+
#
|
5
|
+
# characters = ["Konata", "Kagami", "Tsukasa"]
|
6
|
+
# "Konata".in?(characters) # => true
|
7
|
+
#
|
8
|
+
# This will throw an ArgumentError if the argument doesn't respond
|
9
|
+
# to +#include?+.
|
10
|
+
def in?(*args)
|
11
|
+
if args.length > 1
|
12
|
+
puts "Calling #in? with multiple arguments is" \
|
13
|
+
" deprecated, please pass in an object that responds to #include? instead."
|
14
|
+
args.include? self
|
15
|
+
else
|
16
|
+
another_object = args.first
|
17
|
+
if another_object.respond_to? :include?
|
18
|
+
another_object.include? self
|
19
|
+
else
|
20
|
+
raise ArgumentError.new 'The single parameter passed to #in? must respond to #include?'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Object
|
2
|
+
# Returns a hash with string keys that maps instance variable names without "@" to their
|
3
|
+
# corresponding values.
|
4
|
+
#
|
5
|
+
# class C
|
6
|
+
# def initialize(x, y)
|
7
|
+
# @x, @y = x, y
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
|
12
|
+
def instance_values
|
13
|
+
Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns an array of instance variable names as strings including "@".
|
17
|
+
#
|
18
|
+
# class C
|
19
|
+
# def initialize(x, y)
|
20
|
+
# @x, @y = x, y
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# C.new(0, 1).instance_variable_names # => ["@y", "@x"]
|
25
|
+
def instance_variable_names
|
26
|
+
instance_variables.map { |var| var.to_s }
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class Object
|
2
|
+
# Alias of <tt>to_s</tt>.
|
3
|
+
def to_param
|
4
|
+
to_s
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class NilClass
|
9
|
+
# Returns +self+.
|
10
|
+
def to_param
|
11
|
+
self
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class TrueClass
|
16
|
+
# Returns +self+.
|
17
|
+
def to_param
|
18
|
+
self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class FalseClass
|
23
|
+
# Returns +self+.
|
24
|
+
def to_param
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Array
|
30
|
+
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
31
|
+
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
32
|
+
def to_param
|
33
|
+
collect { |e| e.to_param }.join '/'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Hash
|
38
|
+
# Returns a string representation of the receiver suitable for use as a URL
|
39
|
+
# query string:
|
40
|
+
#
|
41
|
+
# {name: 'David', nationality: 'Danish'}.to_param
|
42
|
+
# # => "name=David&nationality=Danish"
|
43
|
+
#
|
44
|
+
# An optional namespace can be passed to enclose the param names:
|
45
|
+
#
|
46
|
+
# {name: 'David', nationality: 'Danish'}.to_param('user')
|
47
|
+
# # => "user[name]=David&user[nationality]=Danish"
|
48
|
+
#
|
49
|
+
# The string pairs "key=value" that conform the query string
|
50
|
+
# are sorted lexicographically in ascending order.
|
51
|
+
#
|
52
|
+
# This method is also aliased as +to_query+.
|
53
|
+
def to_param(namespace = nil)
|
54
|
+
collect do |key, value|
|
55
|
+
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
56
|
+
end.sort * '&'
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'droiuby/support/object/to_param'
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# Converts an object into a string suitable for use as a URL query string, using the given <tt>key</tt> as the
|
5
|
+
# param name.
|
6
|
+
#
|
7
|
+
# Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
|
8
|
+
def to_query(key)
|
9
|
+
require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
|
10
|
+
"#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Array
|
15
|
+
# Converts an array into a string suitable for use as a URL query string,
|
16
|
+
# using the given +key+ as the param name.
|
17
|
+
#
|
18
|
+
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
|
19
|
+
def to_query(key)
|
20
|
+
prefix = "#{key}[]"
|
21
|
+
collect { |value| value.to_query(prefix) }.join '&'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Hash
|
26
|
+
alias_method :to_query, :to_param
|
27
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class Object
|
2
|
+
# Invokes the public method whose name goes as first argument just like
|
3
|
+
# +public_send+ does, except that if the receiver does not respond to it the
|
4
|
+
# call returns +nil+ rather than raising an exception.
|
5
|
+
#
|
6
|
+
# This method is defined to be able to write
|
7
|
+
#
|
8
|
+
# @person.try(:name)
|
9
|
+
#
|
10
|
+
# instead of
|
11
|
+
#
|
12
|
+
# @person ? @person.name : nil
|
13
|
+
#
|
14
|
+
# +try+ returns +nil+ when called on +nil+ regardless of whether it responds
|
15
|
+
# to the method:
|
16
|
+
#
|
17
|
+
# nil.try(:to_i) # => nil, rather than 0
|
18
|
+
#
|
19
|
+
# Arguments and blocks are forwarded to the method if invoked:
|
20
|
+
#
|
21
|
+
# @posts.try(:each_slice, 2) do |a, b|
|
22
|
+
# ...
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# The number of arguments in the signature must match. If the object responds
|
26
|
+
# to the method the call is attempted and +ArgumentError+ is still raised
|
27
|
+
# otherwise.
|
28
|
+
#
|
29
|
+
# If +try+ is called without arguments it yields the receiver to a given
|
30
|
+
# block unless it is +nil+:
|
31
|
+
#
|
32
|
+
# @person.try do |p|
|
33
|
+
# ...
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# Please also note that +try+ is defined on +Object+, therefore it won't work
|
37
|
+
# with instances of classes that do not have +Object+ among their ancestors,
|
38
|
+
# like direct subclasses of +BasicObject+. For example, using +try+ with
|
39
|
+
# +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
|
40
|
+
# delegator itself.
|
41
|
+
def try(*a, &b)
|
42
|
+
if a.empty? && block_given?
|
43
|
+
yield self
|
44
|
+
else
|
45
|
+
public_send(*a, &b) if respond_to?(a.first)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Same as #try, but will raise a NoMethodError exception if the receiving is not nil and
|
50
|
+
# does not implemented the tried method.
|
51
|
+
def try!(*a, &b)
|
52
|
+
if a.empty? && block_given?
|
53
|
+
yield self
|
54
|
+
else
|
55
|
+
public_send(*a, &b)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class NilClass
|
61
|
+
# Calling +try+ on +nil+ always returns +nil+.
|
62
|
+
# It becomes specially helpful when navigating through associations that may return +nil+.
|
63
|
+
#
|
64
|
+
# nil.try(:name) # => nil
|
65
|
+
#
|
66
|
+
# Without +try+
|
67
|
+
# @person && !@person.children.blank? && @person.children.first.name
|
68
|
+
#
|
69
|
+
# With +try+
|
70
|
+
# @person.try(:children).try(:first).try(:name)
|
71
|
+
def try(*args)
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def try!(*args)
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
|
1
|
+
require 'droiuby/support/object/acts_like'
|
2
|
+
require 'droiuby/support/object/blank'
|
3
|
+
require 'droiuby/support/object/duplicable'
|
4
|
+
require 'droiuby/support/object/deep_dup'
|
5
|
+
require 'droiuby/support/object/try'
|
6
|
+
require 'droiuby/support/object/inclusion'
|
2
7
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def boolean?
|
8
|
-
self.is_a?(TrueClass) || self.is_a?(FalseClass)
|
9
|
-
end
|
10
|
-
|
11
|
-
end
|
8
|
+
require 'droiuby/support/object/instance_variables'
|
9
|
+
|
10
|
+
require 'droiuby/support/object/to_param'
|
11
|
+
require 'droiuby/support/object/to_query'
|
@@ -0,0 +1,104 @@
|
|
1
|
+
class String
|
2
|
+
# If you pass a single Fixnum, returns a substring of one character at that
|
3
|
+
# position. The first character of the string is at position 0, the next at
|
4
|
+
# position 1, and so on. If a range is supplied, a substring containing
|
5
|
+
# characters at offsets given by the range is returned. In both cases, if an
|
6
|
+
# offset is negative, it is counted from the end of the string. Returns nil
|
7
|
+
# if the initial offset falls outside the string. Returns an empty string if
|
8
|
+
# the beginning of the range is greater than the end of the string.
|
9
|
+
#
|
10
|
+
# str = "hello"
|
11
|
+
# str.at(0) #=> "h"
|
12
|
+
# str.at(1..3) #=> "ell"
|
13
|
+
# str.at(-2) #=> "l"
|
14
|
+
# str.at(-2..-1) #=> "lo"
|
15
|
+
# str.at(5) #=> nil
|
16
|
+
# str.at(5..-1) #=> ""
|
17
|
+
#
|
18
|
+
# If a Regexp is given, the matching portion of the string is returned.
|
19
|
+
# If a String is given, that given string is returned if it occurs in
|
20
|
+
# the string. In both cases, nil is returned if there is no match.
|
21
|
+
#
|
22
|
+
# str = "hello"
|
23
|
+
# str.at(/lo/) #=> "lo"
|
24
|
+
# str.at(/ol/) #=> nil
|
25
|
+
# str.at("lo") #=> "lo"
|
26
|
+
# str.at("ol") #=> nil
|
27
|
+
def at(position)
|
28
|
+
self[position]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns a substring from the given position to the end of the string.
|
32
|
+
# If the position is negative, it is counted from the end of the string.
|
33
|
+
#
|
34
|
+
# str = "hello"
|
35
|
+
# str.from(0) #=> "hello"
|
36
|
+
# str.from(3) #=> "lo"
|
37
|
+
# str.from(-2) #=> "lo"
|
38
|
+
#
|
39
|
+
# You can mix it with +to+ method and do fun things like:
|
40
|
+
#
|
41
|
+
# str = "hello"
|
42
|
+
# str.from(0).to(-1) #=> "hello"
|
43
|
+
# str.from(1).to(-2) #=> "ell"
|
44
|
+
def from(position)
|
45
|
+
self[position..-1]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns a substring from the beginning of the string to the given position.
|
49
|
+
# If the position is negative, it is counted from the end of the string.
|
50
|
+
#
|
51
|
+
# str = "hello"
|
52
|
+
# str.to(0) #=> "h"
|
53
|
+
# str.to(3) #=> "hell"
|
54
|
+
# str.to(-2) #=> "hell"
|
55
|
+
#
|
56
|
+
# You can mix it with +from+ method and do fun things like:
|
57
|
+
#
|
58
|
+
# str = "hello"
|
59
|
+
# str.from(0).to(-1) #=> "hello"
|
60
|
+
# str.from(1).to(-2) #=> "ell"
|
61
|
+
def to(position)
|
62
|
+
self[0..position]
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the first character. If a limit is supplied, returns a substring
|
66
|
+
# from the beginning of the string until it reaches the limit value. If the
|
67
|
+
# given limit is greater than or equal to the string length, returns self.
|
68
|
+
#
|
69
|
+
# str = "hello"
|
70
|
+
# str.first #=> "h"
|
71
|
+
# str.first(1) #=> "h"
|
72
|
+
# str.first(2) #=> "he"
|
73
|
+
# str.first(0) #=> ""
|
74
|
+
# str.first(6) #=> "hello"
|
75
|
+
def first(limit = 1)
|
76
|
+
if limit == 0
|
77
|
+
''
|
78
|
+
elsif limit >= size
|
79
|
+
self
|
80
|
+
else
|
81
|
+
to(limit - 1)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns the last character of the string. If a limit is supplied, returns a substring
|
86
|
+
# from the end of the string until it reaches the limit value (counting backwards). If
|
87
|
+
# the given limit is greater than or equal to the string length, returns self.
|
88
|
+
#
|
89
|
+
# str = "hello"
|
90
|
+
# str.last #=> "o"
|
91
|
+
# str.last(1) #=> "o"
|
92
|
+
# str.last(2) #=> "lo"
|
93
|
+
# str.last(0) #=> ""
|
94
|
+
# str.last(6) #=> "hello"
|
95
|
+
def last(limit = 1)
|
96
|
+
if limit == 0
|
97
|
+
''
|
98
|
+
elsif limit >= size
|
99
|
+
self
|
100
|
+
else
|
101
|
+
from(-limit)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class String
|
2
|
+
|
3
|
+
def camelize(first_letter_in_uppercase = true)
|
4
|
+
if first_letter_in_uppercase
|
5
|
+
self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
6
|
+
else
|
7
|
+
self.first + camelize(self)[1..-1]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_pixels
|
12
|
+
Java::com.droiuby.client.core.builder.ActivityBuilder.toPixels(_current_activity, self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_color
|
16
|
+
Java::android.graphics.Color.parseColor(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def underscore
|
20
|
+
self.gsub(/::/, '/').
|
21
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
22
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
23
|
+
tr("-", "_").
|
24
|
+
downcase
|
25
|
+
end
|
26
|
+
|
27
|
+
def constantize
|
28
|
+
names = self.split('::')
|
29
|
+
names.shift if names.empty? || names.first.empty?
|
30
|
+
index = 1
|
31
|
+
names.inject(Object) do |constant, name|
|
32
|
+
if constant == Object
|
33
|
+
constant.const_get(name)
|
34
|
+
else
|
35
|
+
begin
|
36
|
+
candidate = constant.const_get(name)
|
37
|
+
rescue NameError => e
|
38
|
+
Object.const_missing(names[0..index].join('::'))
|
39
|
+
candidate = constant.const_get(name)
|
40
|
+
end
|
41
|
+
index += 1
|
42
|
+
next candidate if constant.const_defined?(name, false)
|
43
|
+
next candidate unless Object.const_defined?(name)
|
44
|
+
|
45
|
+
# Go down the ancestors to check it it's owned
|
46
|
+
# directly before we reach Object or the end of ancestors.
|
47
|
+
constant = constant.ancestors.inject do |const, ancestor|
|
48
|
+
break const if ancestor == Object
|
49
|
+
break ancestor if ancestor.const_defined?(name, false)
|
50
|
+
const
|
51
|
+
end
|
52
|
+
|
53
|
+
# owner is in Object, so raise
|
54
|
+
constant.const_get(name, false)
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class String
|
2
|
+
# The inverse of <tt>String#include?</tt>. Returns true if the string
|
3
|
+
# does not include the other string.
|
4
|
+
#
|
5
|
+
# "hello".exclude? "lo" #=> false
|
6
|
+
# "hello".exclude? "ol" #=> true
|
7
|
+
# "hello".exclude? ?h #=> false
|
8
|
+
def exclude?(string)
|
9
|
+
!include?(string)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class String
|
2
|
+
# Returns the string, first removing all whitespace on both ends of
|
3
|
+
# the string, and then changing remaining consecutive whitespace
|
4
|
+
# groups into one space each.
|
5
|
+
#
|
6
|
+
# Note that it handles both ASCII and Unicode whitespace like mongolian vowel separator (U+180E).
|
7
|
+
#
|
8
|
+
# %{ Multi-line
|
9
|
+
# string }.squish # => "Multi-line string"
|
10
|
+
# " foo bar \n \t boo".squish # => "foo bar boo"
|
11
|
+
def squish
|
12
|
+
dup.squish!
|
13
|
+
end
|
14
|
+
|
15
|
+
# Performs a destructive squish. See String#squish.
|
16
|
+
def squish!
|
17
|
+
gsub!(/\A[[:space:]]+/, '')
|
18
|
+
gsub!(/[[:space:]]+\z/, '')
|
19
|
+
gsub!(/[[:space:]]+/, ' ')
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
# Truncates a given +text+ after a given <tt>length</tt> if +text+ is longer than <tt>length</tt>:
|
24
|
+
#
|
25
|
+
# 'Once upon a time in a world far far away'.truncate(27)
|
26
|
+
# # => "Once upon a time in a wo..."
|
27
|
+
#
|
28
|
+
# Pass a string or regexp <tt>:separator</tt> to truncate +text+ at a natural break:
|
29
|
+
#
|
30
|
+
# 'Once upon a time in a world far far away'.truncate(27, separator: ' ')
|
31
|
+
# # => "Once upon a time in a..."
|
32
|
+
#
|
33
|
+
# 'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
|
34
|
+
# # => "Once upon a time in a..."
|
35
|
+
#
|
36
|
+
# The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...")
|
37
|
+
# for a total length not exceeding <tt>length</tt>:
|
38
|
+
#
|
39
|
+
# 'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
|
40
|
+
# # => "And they f... (continued)"
|
41
|
+
def truncate(truncate_at, options = {})
|
42
|
+
return dup unless length > truncate_at
|
43
|
+
|
44
|
+
options[:omission] ||= '...'
|
45
|
+
length_with_room_for_omission = truncate_at - options[:omission].length
|
46
|
+
stop = \
|
47
|
+
if options[:separator]
|
48
|
+
rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
|
49
|
+
else
|
50
|
+
length_with_room_for_omission
|
51
|
+
end
|
52
|
+
|
53
|
+
"#{self[0...stop]}#{options[:omission]}"
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class String
|
2
|
+
# Same as +indent+, except it indents the receiver in-place.
|
3
|
+
#
|
4
|
+
# Returns the indented string, or +nil+ if there was nothing to indent.
|
5
|
+
def indent!(amount, indent_string=nil, indent_empty_lines=false)
|
6
|
+
indent_string = indent_string || self[/^[ \t]/] || ' '
|
7
|
+
re = indent_empty_lines ? /^/ : /^(?!$)/
|
8
|
+
gsub!(re, indent_string * amount)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Indents the lines in the receiver:
|
12
|
+
#
|
13
|
+
# <<EOS.indent(2)
|
14
|
+
# def some_method
|
15
|
+
# some_code
|
16
|
+
# end
|
17
|
+
# EOS
|
18
|
+
# # =>
|
19
|
+
# def some_method
|
20
|
+
# some_code
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# The second argument, +indent_string+, specifies which indent string to
|
24
|
+
# use. The default is +nil+, which tells the method to make a guess by
|
25
|
+
# peeking at the first indented line, and fallback to a space if there is
|
26
|
+
# none.
|
27
|
+
#
|
28
|
+
# " foo".indent(2) # => " foo"
|
29
|
+
# "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
|
30
|
+
# "foo".indent(2, "\t") # => "\t\tfoo"
|
31
|
+
#
|
32
|
+
# While +indent_string+ is typically one space or tab, it may be any string.
|
33
|
+
#
|
34
|
+
# The third argument, +indent_empty_lines+, is a flag that says whether
|
35
|
+
# empty lines should be indented. Default is false.
|
36
|
+
#
|
37
|
+
# "foo\n\nbar".indent(2) # => " foo\n\n bar"
|
38
|
+
# "foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar"
|
39
|
+
#
|
40
|
+
def indent(amount, indent_string=nil, indent_empty_lines=false)
|
41
|
+
dup.tap {|_| _.indent!(amount, indent_string, indent_empty_lines)}
|
42
|
+
end
|
43
|
+
end
|
@@ -1,60 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def to_pixels
|
12
|
-
Java::com.droiuby.client.core.builder.ActivityBuilder.toPixels(_current_activity, self)
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_color
|
16
|
-
Java::android.graphics.Color.parseColor(self)
|
17
|
-
end
|
18
|
-
|
19
|
-
def underscore
|
20
|
-
self.gsub(/::/, '/').
|
21
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
22
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
23
|
-
tr("-", "_").
|
24
|
-
downcase
|
25
|
-
end
|
26
|
-
|
27
|
-
def constantize
|
28
|
-
names = self.split('::')
|
29
|
-
names.shift if names.empty? || names.first.empty?
|
30
|
-
index = 1
|
31
|
-
names.inject(Object) do |constant, name|
|
32
|
-
if constant == Object
|
33
|
-
constant.const_get(name)
|
34
|
-
else
|
35
|
-
begin
|
36
|
-
candidate = constant.const_get(name)
|
37
|
-
rescue NameError => e
|
38
|
-
Object.const_missing(names[0..index].join('::'))
|
39
|
-
candidate = constant.const_get(name)
|
40
|
-
end
|
41
|
-
index += 1
|
42
|
-
next candidate if constant.const_defined?(name, false)
|
43
|
-
next candidate unless Object.const_defined?(name)
|
44
|
-
|
45
|
-
# Go down the ancestors to check it it's owned
|
46
|
-
# directly before we reach Object or the end of ancestors.
|
47
|
-
constant = constant.ancestors.inject do |const, ancestor|
|
48
|
-
break const if ancestor == Object
|
49
|
-
break ancestor if ancestor.const_defined?(name, false)
|
50
|
-
const
|
51
|
-
end
|
52
|
-
|
53
|
-
# owner is in Object, so raise
|
54
|
-
constant.const_get(name, false)
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
1
|
+
require 'droiuby/support/string/filters'
|
2
|
+
require 'droiuby/support/string/starts_ends_with'
|
3
|
+
require 'droiuby/support/string/access'
|
4
|
+
require 'droiuby/support/string/behavior'
|
5
|
+
require 'droiuby/support/string/exclude'
|
6
|
+
require 'droiuby/support/string/indent'
|
7
|
+
require 'droiuby/support/string/droiuby'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: droiuby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joseph Emmanuel Dayo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -80,20 +80,6 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: activesupport
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
83
|
description: Android app development and rapid prototyping using Ruby
|
98
84
|
email: joseph.dayo@gmail.com
|
99
85
|
executables:
|
@@ -122,7 +108,23 @@ files:
|
|
122
108
|
- lib/droiuby/support/fixnum.rb
|
123
109
|
- lib/droiuby/support/java.rb
|
124
110
|
- lib/droiuby/support/object.rb
|
111
|
+
- lib/droiuby/support/object/acts_like.rb
|
112
|
+
- lib/droiuby/support/object/blank.rb
|
113
|
+
- lib/droiuby/support/object/deep_dup.rb
|
114
|
+
- lib/droiuby/support/object/duplicable.rb
|
115
|
+
- lib/droiuby/support/object/inclusion.rb
|
116
|
+
- lib/droiuby/support/object/instance_variables.rb
|
117
|
+
- lib/droiuby/support/object/to_param.rb
|
118
|
+
- lib/droiuby/support/object/to_query.rb
|
119
|
+
- lib/droiuby/support/object/try.rb
|
125
120
|
- lib/droiuby/support/string.rb
|
121
|
+
- lib/droiuby/support/string/access.rb
|
122
|
+
- lib/droiuby/support/string/behavior.rb
|
123
|
+
- lib/droiuby/support/string/droiuby.rb
|
124
|
+
- lib/droiuby/support/string/exclude.rb
|
125
|
+
- lib/droiuby/support/string/filters.rb
|
126
|
+
- lib/droiuby/support/string/indent.rb
|
127
|
+
- lib/droiuby/support/string/starts_ends_with.rb
|
126
128
|
- lib/droiuby/support/system.rb
|
127
129
|
- lib/droiuby/support/thread.rb
|
128
130
|
- lib/droiuby/support/to_query.rb
|