Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix guides for as core ext #6064

Merged
merged 3 commits into from

4 participants

@gazay

Some fixes in guides for deprecated information and tests for deprecated information about Range#===

/cc @fxn

@steveklabnik
Collaborator

Guides are supposed to be merged into lifo/docrails.

@gazay

@steveklabnik yep, I did it there, but @fxn asked me to pull it here - rails/docrails#94

@steveklabnik
Collaborator

Word. My bad!

@steveklabnik
Collaborator

Ahh, okay. yeah, so after you get your first commit, you get access to push to docrails, and then they go there afterwards.

@fxn
Owner

Actually, docrails has public write access.

This was sent to docrails as a pull request. It is good that is a pull request because a double check will be healthy for this particular edit.

The thing is docrails is not a project, and we do not do pull requests in docrails. docrails is only meant for doc commits people are confident to push themselves. Usually short and non-controversial (see http://weblog.rubyonrails.org/2012/3/7/what-is-docrails/).

So, I asked @gazay to do the pull request here and /cc me.

@steveklabnik
Collaborator

I'll just shut up now. :)

@fxn
Owner

@steveklabnik haha :)

@steveklabnik
Collaborator

:heart:

@gazay

Btw, I think it can be cherry-picked into 3.2.3 stable branch with my previous commit about String#truncate

@vijaydev vijaydev commented on the diff
guides/source/active_support_core_extensions.textile
@@ -2103,20 +2097,20 @@ To do so it sends +to_xml+ to every item in turn, and collects the results under
By default, the name of the root element is the underscorized and dasherized plural of the name of the class of the first item, provided the rest of elements belong to that type (checked with <tt>is_a?</tt>) and they are not hashes. In the example above that's "contributors".
-If there's any element that does not belong to the type of the first one the root node becomes "records":
+If there's any element that does not belong to the type of the first one the root node becomes "objects":
@vijaydev Collaborator
vijaydev added a note

Is there a reason behind this change?

@gazay
gazay added a note

The code for it was changed long time ago - about 2 years 580dd3b#L2L134
I just noticed that guides for this code are deprecated and developer can't get what he expected after reading this line

@vijaydev Collaborator
vijaydev added a note

Got it. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
guides/source/active_support_core_extensions.textile
@@ -2722,8 +2716,6 @@ Active Support extends this method so that the argument may be another range in
(1...9).include?(3..9) # => false
</ruby>
-WARNING: The original +Range#include?+ is still the one aliased to +Range#===+.
@vijaydev Collaborator
vijaydev added a note

Has this changed recently?

@gazay
gazay added a note

This was changed in ruby. In versions >1.9 Range#=== is just an alias of Range#include?
Maybe there is a point to do new commit with alias_method :=== :include_without_range? instead of changing guides for compatibility with previous usage of Range?

@vijaydev Collaborator
vijaydev added a note

@fxn inputs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@fxn
Owner
fxn commented

This pull request touches too many things.

  • :+1: to removing the docs for those class_inheritable_* methods.
  • The documentation of truncate has actually to say that both strings and regexps are valid arguments. It has to say that in English, not implicitly via an example. Examples then could depict each use case.
  • The docs for the time extensions to Numeric are good, but instead of Time.now the equivalence is with Time.current (and the API is wrong here also if I am not mistaken).
  • The comment about Range#include? means that albeit === is an alias of the original method, you don't get these extensions on === (because aliasing is not transitive). So I think the warning should be left as is.

If you revise those it may be good to go. We may copy edit a little bit perhaps later, but no big deal.

@gazay

@fxn I rewrote examples for String#truncate

About Time.now and Time.current - you right, if there set time zone, Time.now.advance will be different with time extensions for Numeric, because they use ::Time.current which returns TimeWithZone object. I rewrote calls to Time.new to Time.current in guides and Numeric docs.

About wrong API - I just took these docs from Numeric extensions file: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/numeric/time.rb#L6 and checked before making this pull request. Also tests passed with this API.

About Range#=== I created gist which explains why this warning should be deleted or new alias should be added as I wrote to @vijaydev: https://gist.github.com/2629683

@fxn
Owner
fxn commented

@gazay gotcha.

Then I think we should document that === is also extended. Both methods are related, and the reader wonders how touching one affects the other one.

@fxn
Owner
fxn commented

Ah, regarding Time.current almost any occurrence of Time.now in the docs is a smell. You almost always want Time.current when working with Rails as a user, and Active Support implements all date and time methods based on Time.current. The application is the one in charge of choosing the time zone, not the machine's clock.

@gazay

@fxn I wrote description for Range#=== gazay@66e0e42#L0L2710

and in one more place changed Time.now to Time.current in guides for AS core_ext

@fxn
Owner
fxn commented

Awesome, thanks for working on this!

@fxn fxn merged commit ed2feb7 into rails:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
6 activesupport/lib/active_support/core_ext/numeric/time.rb
@@ -8,13 +8,13 @@ class Numeric
# These methods use Time#advance for precise date calculations when using from_now, ago, etc.
# as well as adding or subtracting their results from a Time object. For example:
#
- # # equivalent to Time.now.advance(:months => 1)
+ # # equivalent to Time.current.advance(:months => 1)
# 1.month.from_now
#
- # # equivalent to Time.now.advance(:years => 2)
+ # # equivalent to Time.current.advance(:years => 2)
# 2.years.from_now
#
- # # equivalent to Time.now.advance(:months => 4, :years => 5)
+ # # equivalent to Time.current.advance(:months => 4, :years => 5)
# (4.months + 5.years).from_now
#
# While these methods provide precise calculation when used as in the examples above, care
View
12 activesupport/test/core_ext/range_ext_test.rb
@@ -41,6 +41,18 @@ def test_should_include_other_with_exlusive_end
assert((1..10).include?(1...10))
end
+ def test_should_compare_identical_inclusive
+ assert((1..10) === (1..10))
+ end
+
+ def test_should_compare_identical_exclusive
+ assert((1...10) === (1...10))
+ end
+
+ def test_should_compare_other_with_exlusive_end
+ assert((1..10) === (1...10))
+ end
+
def test_exclusive_end_should_not_include_identical_with_inclusive_end
assert !(1...10).include?(1..10)
end
View
132 guides/source/active_support_core_extensions.textile
@@ -184,7 +184,7 @@ You can evaluate code in the context of any object's singleton class using +clas
<ruby>
class Proc
def bind(object)
- block, time = self, Time.now
+ block, time = self, Time.current
object.class_eval do
method_name = "__bind_#{time.to_i}_#{time.usec}"
define_method(method_name, &block)
@@ -1034,49 +1034,6 @@ A model may find it useful to set +:instance_accessor+ to +false+ as a way to pr
NOTE: Defined in +active_support/core_ext/class/attribute_accessors.rb+.
-h4. Class Inheritable Attributes
-
-WARNING: Class Inheritable Attributes are deprecated. It's recommended that you use +Class#class_attribute+ instead.
-
-Class variables are shared down the inheritance tree. Class instance variables are not shared, but they are not inherited either. The macros +class_inheritable_reader+, +class_inheritable_writer+, and +class_inheritable_accessor+ provide accessors for class-level data which is inherited but not shared with children:
-
-<ruby>
-module ActionController
- class Base
- # FIXME: REVISE/SIMPLIFY THIS COMMENT.
- # The value of allow_forgery_protection is inherited,
- # but its value in a particular class does not affect
- # the value in the rest of the controllers hierarchy.
- class_inheritable_accessor :allow_forgery_protection
- end
-end
-</ruby>
-
-They accomplish this with class instance variables and cloning on subclassing, there are no class variables involved. Cloning is performed with +dup+ as long as the value is duplicable.
-
-There are some variants specialised in arrays and hashes:
-
-<ruby>
-class_inheritable_array
-class_inheritable_hash
-</ruby>
-
-Those writers take any inherited array or hash into account and extend them rather than overwrite them.
-
-As with vanilla class attribute accessors these macros create convenience instance methods for reading and writing. The generation of the writer instance method can be prevented setting +:instance_writer+ to +false+ (not any false value, but exactly +false+):
-
-<ruby>
-module ActiveRecord
- class Base
- class_inheritable_accessor :default_scoping, :instance_writer => false
- end
-end
-</ruby>
-
-Since values are copied when a subclass is defined, if the base class changes the attribute after that, the subclass does not see the new value. That's the point.
-
-NOTE: Defined in +active_support/core_ext/class/inheritable_attributes.rb+.
-
h4. Subclasses & Descendants
h5. +subclasses+
@@ -1255,9 +1212,14 @@ Pass a +:separator+ to truncate the string at a natural break:
# => "Oh dear! Oh..."
</ruby>
-In the above example "dear" gets cut first, but then +:separator+ prevents it.
+The option +:separator+ can be a regexp:
+
+<ruby>
+"Oh dear! Oh dear! I shall be late!".truncate(18, :separator => /\s/)
+# => "Oh dear! Oh..."
+</ruby>
-WARNING: The option +:separator+ can't be a regexp.
+In above examples "dear" gets cut first, but then +:separator+ prevents it.
NOTE: Defined in +active_support/core_ext/string/filters.rb+.
@@ -1810,6 +1772,43 @@ Singular forms are aliased so you are able to say:
NOTE: Defined in +active_support/core_ext/numeric/bytes.rb+.
+h4. Time
+
+Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
+
+These methods use Time#advance for precise date calculations when using from_now, ago, etc.
+as well as adding or subtracting their results from a Time object. For example:
+
+<ruby>
+# equivalent to Time.current.advance(:months => 1)
+1.month.from_now
+
+# equivalent to Time.current.advance(:years => 2)
+2.years.from_now
+
+# equivalent to Time.current.advance(:months => 4, :years => 5)
+(4.months + 5.years).from_now
+</ruby>
+
+While these methods provide precise calculation when used as in the examples above, care
+should be taken to note that this is not true if the result of `months', `years', etc is
+converted before use:
+
+<ruby>
+# equivalent to 30.days.to_i.from_now
+1.month.to_i.from_now
+
+# equivalent to 365.25.days.to_f.from_now
+1.year.to_f.from_now
+</ruby>
+
+In such cases, Ruby's core
+Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
+Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
+date and time arithmetic.
+
+NOTE: Defined in +active_support/core_ext/numeric/time.rb+.
+
h3. Extensions to +Integer+
h4. +multiple_of?+
@@ -2103,20 +2102,20 @@ To do so it sends +to_xml+ to every item in turn, and collects the results under
By default, the name of the root element is the underscorized and dasherized plural of the name of the class of the first item, provided the rest of elements belong to that type (checked with <tt>is_a?</tt>) and they are not hashes. In the example above that's "contributors".
-If there's any element that does not belong to the type of the first one the root node becomes "records":
+If there's any element that does not belong to the type of the first one the root node becomes "objects":
@vijaydev Collaborator
vijaydev added a note

Is there a reason behind this change?

@gazay
gazay added a note

The code for it was changed long time ago - about 2 years 580dd3b#L2L134
I just noticed that guides for this code are deprecated and developer can't get what he expected after reading this line

@vijaydev Collaborator
vijaydev added a note

Got it. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
<ruby>
[Contributor.first, Commit.first].to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
-# <records type="array">
-# <record>
+# <objects type="array">
+# <object>
# <id type="integer">4583</id>
# <name>Aaron Batalion</name>
# <rank type="integer">53</rank>
# <url-id>aaron-batalion</url-id>
-# </record>
-# <record>
+# </object>
+# <object>
# <author>Joshua Peek</author>
# <authored-timestamp type="datetime">2009-09-02T16:44:36Z</authored-timestamp>
# <branch>origin/master</branch>
@@ -2127,30 +2126,30 @@ If there's any element that does not belong to the type of the first one the roo
# <imported-from-svn type="boolean">false</imported-from-svn>
# <message>Kill AMo observing wrap_with_notifications since ARes was only using it</message>
# <sha1>723a47bfb3708f968821bc969a9a3fc873a3ed58</sha1>
-# </record>
-# </records>
+# </object>
+# </objects>
</ruby>
-If the receiver is an array of hashes the root element is by default also "records":
+If the receiver is an array of hashes the root element is by default also "objects":
<ruby>
[{:a => 1, :b => 2}, {:c => 3}].to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
-# <records type="array">
-# <record>
+# <objects type="array">
+# <object>
# <b type="integer">2</b>
# <a type="integer">1</a>
-# </record>
-# <record>
+# </object>
+# <object>
# <c type="integer">3</c>
-# </record>
-# </records>
+# </object>
+# </objects>
</ruby>
WARNING. If the collection is empty the root element is by default "nil-classes". That's a gotcha, for example the root element of the list of contributors above would not be "contributors" if the collection was empty, but "nil-classes". You may use the <tt>:root</tt> option to ensure a consistent root element.
-The name of children nodes is by default the name of the root node singularized. In the examples above we've seen "contributor" and "record". The option <tt>:children</tt> allows you to set these node names.
+The name of children nodes is by default the name of the root node singularized. In the examples above we've seen "contributor" and "object". The option <tt>:children</tt> allows you to set these node names.
The default XML builder is a fresh instance of <tt>Builder::XmlMarkup</tt>. You can configure your own builder via the <tt>:builder</tt> option. The method also accepts options like <tt>:dasherize</tt> and friends, they are forwarded to the builder:
@@ -2707,22 +2706,25 @@ NOTE: Defined in +active_support/core_ext/range/blockless_step.rb+.
h4. +include?+
-The method +Range#include?+ says whether some value falls between the ends of a given instance:
+The methods +Range#include?+ and +Range#===+ say whether some value falls between the ends of a given instance:
<ruby>
(2..3).include?(Math::E) # => true
</ruby>
-Active Support extends this method so that the argument may be another range in turn. In that case we test whether the ends of the argument range belong to the receiver themselves:
+Active Support extends these methods so that the argument may be another range in turn. In that case we test whether the ends of the argument range belong to the receiver themselves:
<ruby>
(1..10).include?(3..7) # => true
(1..10).include?(0..7) # => false
(1..10).include?(3..11) # => false
(1...9).include?(3..9) # => false
-</ruby>
-WARNING: The original +Range#include?+ is still the one aliased to +Range#===+.
+(1..10) === (3..7) # => true
+(1..10) === (0..7) # => false
+(1..10) === (3..11) # => false
+(1...9) === (3..9) # => false
+</ruby>
NOTE: Defined in +active_support/core_ext/range/include_range.rb+.
Something went wrong with that request. Please try again.