1 Kaip įkelti pagrindinius plėtinius
1.1 Stand-alone Aktyvusis palaikymas
Norint turėti kuo mažesnį numatytąjį atminties našumą, Aktyvusis palaikymas numatytai įkelia minimalias priklausomybes. Jis yra padalintas į mažas dalis, todėl galima įkelti tik norimus plėtinius. Taip pat yra patogūs įėjimo taškai, skirti įkelti susijusius plėtinius vienu metu, netgi viską.
Taigi, po paprasto require
:
require "active_support"
bus įkelti tik Aktyvusiojo palaikymo pagrindiniai plėtiniai.
1.1.1 Pasirinktinio apibrėžimo pasirinkimas
Šis pavyzdys parodo, kaip įkelti Hash#with_indifferent_access
. Šis plėtinys leidžia konvertuoti Hash
į ActiveSupport::HashWithIndifferentAccess
, kuris leidžia prieigą prie raktų kaip prie simbolių arba kaip prie eilučių.
{ a: 1 }.with_indifferent_access["a"] # => 1
Kiekvienam vienam kaip pagrindinio plėtinio apibrėžtam metodui šiame vadove yra pastaba, kur nurodoma, kur toks metodas yra apibrėžtas. with_indifferent_access
atveju pastaba skaitoma taip:
PASTABA: Apibrėžta active_support/core_ext/hash/indifferent_access.rb
.
Tai reiškia, kad jūs galite tai įkelti taip:
require "active_support"
require "active_support/core_ext/hash/indifferent_access"
Aktyvusis palaikymas buvo kruopščiai peržiūrėtas, todėl pasirinkus failą, įkeliamos tik griežtai reikalingos priklausomybės, jei tokių yra.
1.1.2 Grupuotų pagrindinių plėtinių įkėlimas
Kitas lygis yra tiesiog įkelti visus Hash
plėtinius. Taisyklės pagalba, SomeClass
plėtiniai yra pasiekiami vienu metu, įkeliant active_support/core_ext/some_class
.
Taigi, norint įkelti visus Hash
plėtinius (įskaitant with_indifferent_access
):
require "active_support"
require "active_support/core_ext/hash"
1.1.3 Visų pagrindinių plėtinių įkėlimas
Galbūt norėsite tiesiog įkelti visus pagrindinius plėtinius, tam yra failas:
require "active_support"
require "active_support/core_ext"
1.1.4 Viso Aktyvaus palaikymo įkėlimas
Ir galiausiai, jei norite turėti visą Aktyvųjį palaikymą, tiesiog naudokite:
require "active_support/all"
Tai net neįkelia viso Aktyvaus palaikymo į atmintį iš karto, iš tikrųjų, kai kurie dalykai yra sukonfigūruoti per autoload
, todėl jie įkeliami tik naudojant.
1.2 Aktyvusis palaikymas Ruby on Rails aplikacijoje
Ruby on Rails aplikacija įkelia visą Aktyvųjį palaikymą, nebent config.active_support.bare
yra true
. Tokiu atveju aplikacija įkelia tik tai, ką pati sistema pasirenka savo poreikiams, ir vis tiek gali pasirinkti pati, kaip paaiškinta ankstesniame skyriuje.
2 Plėtiniai visiems objektams
2.1 blank?
ir present?
Rails aplikacijoje šie reikšmės laikomos tuščiomis:
nil
irfalse
,eilutės, sudarytos tik iš tarpų (žr. pastabą žemiau),
tuščios masyvai ir žodynai, ir
bet koks kitas objektas, kuris atsako į
empty?
ir yra tuščias.
INFORMACIJA: Eilučių predikatas naudoja Unikodo sąmoningą simbolių klasę [:space:]
, todėl pavyzdžiui U+2029 (pastraipos skirtukas) laikomas tarpais.
ĮSPĖJIMAS: Atkreipkite dėmesį, kad čia nėra paminėti skaičiai. Ypač, 0 ir 0.0 nėra tušti.
Pavyzdžiui, ši ActionController::HttpAuthentication::Token::ControllerMethods
klasės metodas naudoja blank?
tikrinimui, ar yra pateiktas ženklas:
def authenticate(controller, &login_procedure)
token, options = token_and_options(controller.request)
unless token.blank?
login_procedure.call(token, options)
end
end
Metodas present?
yra ekvivalentus !blank?
. Šis pavyzdys paimtas iš ActionDispatch::Http::Cache::Response
klasės:
def set_conditional_cache_control!
return if self["Cache-Control"].present?
# ...
end
PASTABA: Apibrėžta active_support/core_ext/object/blank.rb
faile.
2.2 presence
presence
metodas grąžina savo gavėją, jei present?
, ir nil
kitu atveju. Tai naudinga idiomoms, panašioms į šią:
host = config[:host].presence || 'localhost'
PASTABA: Apibrėžta active_support/core_ext/object/blank.rb
faile.
2.3 duplicable?
Nuo Ruby 2.5 dauguma objektų gali būti kopijuojami naudojant dup
arba clone
:
"foo".dup # => "foo"
"".dup # => ""
Rational(1).dup # => (1/1)
Complex(0).dup # => (0+0i)
1.method(:+).dup # => TypeError (allocator undefined for Method)
Active Support teikia duplicable?
metodą, skirtą užklausti objektą apie tai:
"foo".duplicable? # => true
"".duplicable? # => true
Rational(1).duplicable? # => true
Complex(1).duplicable? # => true
1.method(:+).duplicable? # => false
ĮSPĖJIMAS: Bet kuri klasė gali neleisti kopijavimo pašalinant dup
ir clone
arba iškeliant iš jų išimtis. Todėl tik rescue
gali pasakyti, ar duotas objektas yra kopijuojamas. duplicable?
priklauso nuo aukščiau pateiktos sąrašo, bet jis yra daug greitesnis nei rescue
. Jį naudokite tik jei žinote, kad aukščiau pateiktas sąrašas pakanka jūsų naudojimo atveju.
PASTABA: Apibrėžta active_support/core_ext/object/duplicable.rb
faile.
2.4 deep_dup
deep_dup
metodas grąžina gilų norimo objekto kopiją. Paprastai, kai kopijuojate objektą, kuris turi kitus objektus, Ruby jų nekopijuoja, todėl sukuria paviršinę objekto kopiją. Jei turite masyvą su eilute, pavyzdžiui, tai atrodytų taip:
array = ['string']
duplicate = array.dup
duplicate.push 'another-string'
# objektas buvo nukopijuotas, todėl elementas buvo pridėtas tik prie kopijos
array # => ['string']
duplicate # => ['string', 'another-string']
duplicate.first.gsub!('string', 'foo')
# pirmas elementas nebuvo nukopijuotas, jis bus pakeistas abiejuose masyvuose
array # => ['foo']
duplicate # => ['foo', 'another-string']
Kaip matote, nukopijuojant Array
objektą, gavome kitą objektą, todėl galime jį modifikuoti ir originalus objektas liks nepakeistas. Tačiau tai netaikoma masyvo elementams. Kadangi dup
nekopijuoja giliai, eilutė masyve vis dar yra tas pats objektas.
Jei jums reikia gilos objekto kopijos, turėtumėte naudoti deep_dup
. Štai pavyzdys:
array = ['string']
duplicate = array.deep_dup
duplicate.first.gsub!('string', 'foo')
array # => ['string']
duplicate # => ['foo']
Jei objektas negali būti kopijuojamas, deep_dup
tiesiog jį grąžins:
number = 1
duplicate = number.deep_dup
number.object_id == duplicate.object_id # => true
PASTABA: Apibrėžta active_support/core_ext/object/deep_dup.rb
faile.
2.5 try
Kai norite iškviesti metodą objekte tik tuo atveju, jei jis nėra nil
, paprasčiausias būdas tai pasiekti yra naudojant sąlyginės instrukcijas, kurios prideda nereikalingą šlamšą. Alternatyva yra naudoti try
. try
yra panašus į Object#public_send
, tik grąžina nil
, jei yra išsiųstas į nil
.
Štai pavyzdys:
# be try
unless @number.nil?
@number.next
end
# su try
@number.try(:next)
Kitas pavyzdys yra šis kodas iš ActiveRecord::ConnectionAdapters::AbstractAdapter
, kur @logger
gali būti nil
. Matote, kad kodas naudoja try
ir vengia nereikalingo patikrinimo.
def log_info(sql, name, ms)
if @logger.try(:debug?)
name = '%s (%.1fms)' % [name || 'SQL', ms]
@logger.debug(format_log_entry(name, sql.squeeze(' ')))
end
end
try
taip pat gali būti iškviestas be argumentų, bet su bloku, kuris bus vykdomas tik tada, jei objektas nėra nil
:
@person.try { |p| "#{p.first_name} #{p.last_name}" }
Atkreipkite dėmesį, kad try
praryja nėra-metodo klaidas ir grąžina nil
vietoj to. Jei norite apsisaugoti nuo klaidų rašyme, naudokite try!
:
@number.try(:nest) # => nil
@number.try!(:nest) # NoMethodError: undefined method `nest' for 1:Integer
Pastaba: Apibrėžta active_support/core_ext/object/try.rb
.
2.6 class_eval(*args, &block)
Galite įvertinti kodą bet kurio objekto vienintelės klasės kontekste naudodami class_eval
:
class Proc
def bind(object)
block, time = self, Time.current
object.class_eval do
method_name = "__bind_#{time.to_i}_#{time.usec}"
define_method(method_name, &block)
method = instance_method(method_name)
remove_method(method_name)
method
end.bind(object)
end
end
Pastaba: Apibrėžta active_support/core_ext/kernel/singleton_class.rb
.
2.7 acts_like?(duck)
Metodas acts_like?
suteikia galimybę patikrinti, ar tam tikra klasė elgiasi kaip kita klasė pagal paprastą konvenciją: klasė, kuri teikia tą pačią sąsają kaip String
, apibrėžia
def acts_like_string?
end
tai tik žymeklis, jos kūnas ar grąžinimo reikšmė nėra svarbūs. Tada kliento kodas gali užklausti, ar tam tikra klasė yra tinkama šiam tipui:
some_klass.acts_like?(:string)
Rails turi klases, kurios elgiasi kaip Date
ar Time
ir laikosi šio kontrakto.
Pastaba: Apibrėžta active_support/core_ext/object/acts_like.rb
.
2.8 to_param
Visi objektai Rails atsako į metodą to_param
, kuris turėtų grąžinti kažką, kas juos atstovauja kaip reikšmes užklausos eilutėje arba URL fragmentuose.
Pagal numatytuosius nustatymus to_param
tiesiog iškviečia to_s
:
7.to_param # => "7"
to_param
grąžinimo reikšmė neturėtų būti pabėgta:
"Tom & Jerry".to_param # => "Tom & Jerry"
Kelių klasės Rails perrašo šį metodą.
Pavyzdžiui, nil
, true
ir false
grąžina save. Array#to_param
iškviečia to_param
ant elementų ir sujungia rezultatą su "/":
[0, true, String].to_param # => "0/true/String"
Ypatingai, Rails maršrutizavimo sistema iškviečia to_param
ant modelių, kad gautų reikšmę :id
vietos rezervuotajam žymekliui. ActiveRecord::Base#to_param
grąžina modelio id
, bet galite pervardyti šį metodą savo modeliuose. Pavyzdžiui, turint
class User
def to_param
"#{id}-#{name.parameterize}"
end
end
gauname:
user_path(@user) # => "/users/357-john-smith"
ĮSPĖJIMAS. Valdikliai turi žinoti apie bet kokį to_param
pervardijimą, nes kai toks užklaustas užklausas, "357-john-smith" yra params[:id]
reikšmė.
Pastaba: Apibrėžta active_support/core_ext/object/to_param.rb
.
2.9 to_query
Metodas to_query
sukuria užklausos eilutę, kuri susieja tam tikrą key
su to_param
grąžinimo reikšme. Pavyzdžiui, turint šią to_param
apibrėžtį:
class User
def to_param
"#{id}-#{name.parameterize}"
end
end
gauname:
current_user.to_query('user') # => "user=357-john-smith"
Šis metodas pabėga viską, kas reikalinga, tiek raktui, tiek reikšmei:
account.to_query('company[name]')
# => "company%5Bname%5D=Johnson+%26+Johnson"
todėl jo išvestis yra paruošta naudoti užklausos eilutėje.
Masyvai grąžina rezultatą, taikant to_query
kiekvienam elementui su key[]
kaip raktu, ir sujungia rezultatą su "&":
[3.4, -45.6].to_query('sample')
# => "sample%5B%5D=3.4&sample%5B%5D=-45.6"
Taip pat, hash'ai taip pat gali būti panaudojami su to_query
, bet su kitokia sintakse. Jei nėra perduodamo argumento, kvietimas generuoja surūšiuotą raktų/vertės priskyrimų seriją, kviečiant to_query(key)
jo reikšmes. Tada rezultatas sujungiamas su "&":
{ c: 3, b: 2, a: 1 }.to_query # => "a=1&b=2&c=3"
Metodas Hash#to_query
priima pasirinktiną vardų erdvę raktams:
{ id: 89, name: "John Smith" }.to_query('user')
# => "user%5Bid%5D=89&user%5Bname%5D=John+Smith"
PASTABA: Apibrėžta active_support/core_ext/object/to_query.rb
.
2.10 with_options
Metodas with_options
suteikia būdą išskirti bendrus parametrus iš eilės metodų kvietimų.
Turint numatytąjį parametrų hash'ą, with_options
perduoda proxy objektą į bloką. Bloke, metodai, iškviesti per proxy, perduodami gavėjui su sujungtais parametrais. Pavyzdžiui, galite atsikratyti dublikavimo:
class Account < ApplicationRecord
has_many :customers, dependent: :destroy
has_many :products, dependent: :destroy
has_many :invoices, dependent: :destroy
has_many :expenses, dependent: :destroy
end
šitaip:
class Account < ApplicationRecord
with_options dependent: :destroy do |assoc|
assoc.has_many :customers
assoc.has_many :products
assoc.has_many :invoices
assoc.has_many :expenses
end
end
Toks idiomas taip pat gali perduoti grupavimą skaitytojui. Pavyzdžiui, sakykite, norite išsiųsti naujienlaiškį, kurio kalba priklauso nuo vartotojo. Kažkur pašto siuntėjime galėtumėte grupuoti lokalės priklausančius dalykus šitaip:
I18n.with_options locale: user.locale, scope: "newsletter" do |i18n|
subject i18n.t :subject
body i18n.t :body, user_name: user.name
end
PATARIMAS: Kadangi with_options
perduoda kvietimus gavėjui, jie gali būti įdėti vienas į kitą. Kiekvienas įdėjimo lygis sujungs paveldėtus numatytuosius parametrus, be savųjų.
PASTABA: Apibrėžta active_support/core_ext/object/with_options.rb
.
2.11 JSON palaikymas
Active Support teikia geresnį to_json
įgyvendinimą nei įprastai json
gembė Ruby objektams. Tai yra todėl, kad kai kurie klasės, pvz., Hash
ir Process::Status
, reikalauja specialaus tvarkymo, kad būtų gautas tinkamas JSON atvaizdavimas.
PASTABA: Apibrėžta active_support/core_ext/object/json.rb
.
2.12 Egzemplioriaus kintamieji
Active Support teikia keletą metodų, palengvinančių prieigą prie egzemplioriaus kintamųjų.
2.12.1 instance_values
Metodas instance_values
grąžina hash'ą, kuris susieja egzemplioriaus kintamųjų pavadinimus be "@" su atitinkamomis reikšmėmis. Raktai yra eilutės:
class C
def initialize(x, y)
@x, @y = x, y
end
end
C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
PASTABA: Apibrėžta active_support/core_ext/object/instance_variables.rb
.
2.12.2 instance_variable_names
Metodas instance_variable_names
grąžina masyvą. Kiekvienas pavadinimas įtraukia "@" ženklą.
class C
def initialize(x, y)
@x, @y = x, y
end
end
C.new(0, 1).instance_variable_names # => ["@x", "@y"]
PASTABA: Apibrėžta active_support/core_ext/object/instance_variables.rb
.
2.13 Klaidų ir išimčių slopinimas
Metodai silence_warnings
ir enable_warnings
pakeičia $VERBOSE
reikšmę atitinkamai per jų bloką ir po to ją atstatydina:
silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
Klaidų slopinimas taip pat yra įmanomas naudojant suppress
. Šis metodas priima bet kokį išimčių klasės skaičių. Jei išimtis iškyla vykdant bloką ir yra kind_of?
bet kurio iš argumentų, suppress
ją sugauna ir grąžina tyliai. Kitu atveju išimtis nėra sugaunama:
```ruby
Jei naudotojas yra užrakintas, padidinimas yra prarandamas, tai nėra didelė problema.
suppress(ActiveRecord::StaleObjectError) do current_user.increment! :visits end ```
PASTABA: Apibrėžta active_support/core_ext/kernel/reporting.rb
.
2.14 in?
Predikatas in?
patikrina, ar objektas yra įtrauktas į kitą objektą. Jei perduotas argumentas neatitinka include?
metodo, bus iškelta ArgumentError
išimtis.
in?
pavyzdžiai:
1.in?([1, 2]) # => true
"lo".in?("hello") # => true
25.in?(30..50) # => false
1.in?(1) # => ArgumentError
PASTABA: Apibrėžta active_support/core_ext/object/inclusion.rb
.
3 Plėtiniai Module
3.1 Atributai
3.1.1 alias_attribute
Modelio atributai turi skaitytuvo, rašytojo ir predikato metodus. Galite sukurti modelio atributą, kuriam visi trys metodai yra apibrėžti naudojant alias_attribute
metodą. Kaip ir kituose sinonimų kūrimo metodų atveju, naujas pavadinimas yra pirmas argumentas, o senas pavadinimas yra antras (vienas mnemoninis būdas yra tai, kad jie eina tokiu pačiu tvarka, kaip ir priskyrimo atveju):
class User < ApplicationRecord
# Galite kreiptis į el. pašto stulpelį kaip "login".
# Tai gali būti prasminga autentifikacijos kodo atveju.
alias_attribute :login, :email
end
PASTABA: Apibrėžta active_support/core_ext/module/aliasing.rb
.
3.1.2 Vidiniai atributai
Kai apibrėžiate atributą klasėje, kuri skirta paveldėti, pavadinimo susidūrimai yra rizika. Tai yra ypatingai svarbu bibliotekoms.
Active Support apibrėžia makrokomandas attr_internal_reader
, attr_internal_writer
ir attr_internal_accessor
. Jos elgiasi kaip jų įmontuoti Ruby attr_*
atitikmenys, išskyrus tai, kad jos pavadina pagrindinį egzemplioriaus kintamąjį taip, kad susidūrimai būtų mažiau tikėtini.
Makrokomanda attr_internal
yra sinonimas attr_internal_accessor
:
# biblioteka
class ThirdPartyLibrary::Crawler
attr_internal :log_level
end
# kliento kodas
class MyCrawler < ThirdPartyLibrary::Crawler
attr_accessor :log_level
end
Ankstesniame pavyzdyje gali būti atvejis, kai :log_level
nepriklauso bibliotekos viešajai sąsajai ir jis naudojamas tik vystymui. Kliento kodas, nežinodamas apie galimą konfliktą, paveldi ir apibrėžia savo :log_level
. Dėka attr_internal
nėra susidūrimo.
Pagal numatytuosius nustatymus vidinio egzemplioriaus kintamasis vadinamas su priešakyje esančiu pabraukimu, pvz., @_log_level
aukščiau pateiktame pavyzdyje. Tai galima konfigūruoti naudojant Module.attr_internal_naming_format
, galite perduoti bet kokį sprintf
tipo formatavimo eilutę su priešakyje esančiu @
ir kur nors esančiu %s
, kur bus įdėtas pavadinimas. Numatytasis yra "@_%s"
.
Rails naudoja vidinius atributus keliuose vietose, pavyzdžiui, rodiniams:
module ActionView
class Base
attr_internal :captures
attr_internal :request, :layout
attr_internal :controller, :template
end
end
PASTABA: Apibrėžta active_support/core_ext/module/attr_internal.rb
.
3.1.3 Modulio atributai
Makrokomandos mattr_reader
, mattr_writer
ir mattr_accessor
yra tokios pačios kaip ir klasės cattr_*
makrokomandos. Iš tikrųjų, cattr_*
makrokomandos yra tik sinonimai mattr_*
makrokomandoms. Žr. Klasės atributai.
Pavyzdžiui, Active Storage žurnalo API yra generuojama naudojant mattr_accessor
:
module ActiveStorage
mattr_accessor :logger
end
PASTABA: Apibrėžta active_support/core_ext/module/attribute_accessors.rb
.
3.2 Tėvai
3.2.1 module_parent
Įdėtame vardiniame modulyje esančio module_parent
metodas grąžina modulį, kuriame yra atitinkantis konstanta:
module X
module Y
module Z
end
end
end
M = X::Y::Z
X::Y::Z.module_parent # => X::Y
M.module_parent # => X::Y
Jei modulis yra anoniminis arba priklauso viršutinei lygybei, module_parent
grąžina Object
.
ĮSPĖJIMAS: Atkreipkite dėmesį, kad šiuo atveju module_parent_name
grąžina nil
.
PASTABA: Apibrėžta active_support/core_ext/module/introspection.rb
faile.
3.2.2 module_parent_name
Metodas module_parent_name
sujungtoje vardų modulyje grąžina visiškai kvalifikuotą modulio pavadinimą, kuris yra jo atitinkamo kintamojo viduje:
module X
module Y
module Z
end
end
end
M = X::Y::Z
X::Y::Z.module_parent_name # => "X::Y"
M.module_parent_name # => "X::Y"
Viršutiniu lygiu arba anoniminiuose moduliuose module_parent_name
grąžina nil
.
ĮSPĖJIMAS: Atkreipkite dėmesį, kad šiuo atveju module_parent
grąžina Object
.
PASTABA: Apibrėžta active_support/core_ext/module/introspection.rb
faile.
3.2.3 module_parents
Metodas module_parents
iškviečia module_parent
gavėją ir juda aukštyn, kol pasiekiamas Object
. Šis grandinė grąžinama masyve, nuo apačios iki viršaus:
module X
module Y
module Z
end
end
end
M = X::Y::Z
X::Y::Z.module_parents # => [X::Y, X, Object]
M.module_parents # => [X::Y, X, Object]
PASTABA: Apibrėžta active_support/core_ext/module/introspection.rb
faile.
3.3 Anoniminiai
Modulis gali turėti arba neturėti pavadinimo:
module M
end
M.name # => "M"
N = Module.new
N.name # => "N"
Module.new.name # => nil
Galite patikrinti, ar modulis turi pavadinimą naudodami predikatą anonymous?
:
module M
end
M.anonymous? # => false
Module.new.anonymous? # => true
Atkreipkite dėmesį, kad būti nepasiekiamam nereiškia būti anonimiškam:
module M
end
m = Object.send(:remove_const, :M)
m.anonymous? # => false
tačiau anoniminis modulis apibrėžiamas pagal apibrėžimą yra nepasiekiamas.
PASTABA: Apibrėžta active_support/core_ext/module/anonymous.rb
faile.
3.4 Metodų Delegavimas
3.4.1 delegate
Makro delegate
siūlo paprastą būdą persiųsti metodus.
Pavyzdžiui, įsivaizduokite, kad vartotojai tam tikroje aplikacijoje turi prisijungimo informaciją User
modelyje, o vardą ir kitus duomenis atskirame Profile
modelyje:
class User < ApplicationRecord
has_one :profile
end
Su tokia konfigūracija vartotojo vardą galite gauti per jų profilį, user.profile.name
, tačiau būtų patogu vis tiek galėti tiesiogiai pasiekti tokius atributus:
class User < ApplicationRecord
has_one :profile
def name
profile.name
end
end
Tai daro delegate
už jus:
class User < ApplicationRecord
has_one :profile
delegate :name, to: :profile
end
Tai yra trumpesnis ir aiškesnis.
Metodas turi būti viešas tikslui.
delegate
makras priima kelis metodus:
delegate :name, :age, :address, :twitter, to: :profile
Kai įterpiamas į eilutę, :to
parinktis turėtų tapti išraiška, kuri įvertina metodui persiųstą objektą. Paprastai tai yra eilutė arba simbolis. Tokia išraiška įvertinama gavėjo kontekste:
# persiunčia į Rails konstantą
delegate :logger, to: :Rails
# persiunčia į gavėjo klasę
delegate :table_name, to: :class
ĮSPĖJIMAS: Jei :prefix
parinktis yra true
, tai yra mažiau universalu, žr. žemiau.
Pagal numatytuosius nustatymus, jei delegavimas sukelia NoMethodError
ir tikslas yra nil
, išimtis yra perduodama. Galite paprašyti, kad vietoj to būtų grąžinamas nil
naudojant :allow_nil
parinktį:
delegate :name, to: :profile, allow_nil: true
Su :allow_nil
kvietimas user.name
grąžina nil
, jei vartotojas neturi profilio.
prefix
parinktis prideda priešdėlį prie sugeneruoto metodo pavadinimo. Tai gali būti patogu, pavyzdžiui, gauti geresnį pavadinimą:
ruby
delegate :gatvė, to: :adresas, prefix: true
Ankstesnis pavyzdys generuoja adresas_gatvė
vietoje gatvė
.
ĮSPĖJIMAS: Kadangi šiuo atveju sugeneruoto metodo pavadinimas sudarytas iš tikslinio objekto ir tikslinio metodo pavadinimų, :to
parinktis turi būti metodo pavadinimas.
Taip pat galima konfigūruoti pasirinktinį priešdėlį:
delegate :dydis, to: :priedas, prefix: :avataras
Ankstesniame pavyzdyje makro generuoja avataras_dydis
vietoje dydis
.
Parinktis :private
keičia metodų matomumo sritį:
delegate :gimimo_data, to: :profilis, private: true
Perduodami metodai pagal numatytuosius nustatymus yra vieši. Norėdami tai pakeisti, perduokite private: true
.
PASTABA: Apibrėžta active_support/core_ext/module/delegation.rb
3.4.2 delegate_missing_to
Įsivaizduokite, kad norite perduoti viską, kas trūksta iš Vartotojo
objekto, į Profilio
objektą. delegate_missing_to
makras leidžia jums tai įgyvendinti lengvai:
class Vartotojas < ApplicationRecord
has_one :profilis
delegate_missing_to :profilis
end
Tikslas gali būti bet kas, kas gali būti iškviesta objekte, pvz., objekto kintamieji, metodai, konstantos ir kt. Tik vieši tikslinio objekto metodai yra perduodami.
PASTABA: Apibrėžta active_support/core_ext/module/delegation.rb
.
3.5 Metodų persikūrimas
Yra atvejų, kai jums reikia apibrėžti metodą su define_method
, bet nežinote, ar toks metodas jau egzistuoja. Jei taip, išspausdinamas įspėjimas, jei jie yra įjungti. Tai nėra didelė problema, bet ir nešvaru.
Metodas redefine_method
užkerta kelią galimam įspėjimui, pašalindamas esamą metodą, jei reikia.
Taip pat galite naudoti silence_redefinition_of_method
, jei norite apibrėžti
pakeitimo metodą patys (pavyzdžiui, naudojant delegate
).
PASTABA: Apibrėžta active_support/core_ext/module/redefine_method.rb
.
4 Plėtiniai Class
4.1 Klasės atributai
4.1.1 class_attribute
Metodas class_attribute
deklaruoja vieną ar daugiau paveldimų klasės atributų, kurie gali būti perrašomi bet kurioje hierarchijos lygyje.
class A
class_attribute :x
end
class B < A; end
class C < B; end
A.x = :a
B.x # => :a
C.x # => :a
B.x = :b
A.x # => :a
C.x # => :b
C.x = :c
A.x # => :a
B.x # => :b
Pavyzdžiui, ActionMailer::Base
apibrėžia:
class_attribute :default_params
self.default_params = {
mime_version: "1.0",
charset: "UTF-8",
content_type: "text/plain",
parts_order: [ "text/plain", "text/enriched", "text/html" ]
}.freeze
Jie taip pat gali būti pasiekiami ir perrašomi objekto lygyje.
A.x = 1
a1 = A.new
a2 = A.new
a2.x = 2
a1.x # => 1, ateina iš A
a2.x # => 2, perrašyta a2
Rašytojo objekto metodo generavimą galima išvengti nustatant parinktį :instance_writer
į false
.
module ActiveRecord
class Base
class_attribute :table_name_prefix, instance_writer: false, default: "my"
end
end
Modeliui gali būti naudinga ši parinktis kaip būdas užkirsti kelią masiniam priskyrimui nustatant atributą.
Skaitytojo objekto metodo generavimą galima išvengti nustatant parinktį :instance_reader
į false
.
class A
class_attribute :x, instance_reader: false
end
A.new.x = 1
A.new.x # NoMethodError
Patogumui class_attribute
taip pat apibrėžia objekto predikatą, kuris yra dvigubas neigimas to, ką grąžina objekto skaitytuvas. Pavyzdžiuose jis būtų pavadintas x?
.
Kai :instance_reader
yra false
, egzemplioriaus predikatas grąžina NoMethodError
, kaip ir skaitymo metodas.
Jei nenorite egzemplioriaus predikato, perduokite instance_predicate: false
, ir jis nebus apibrėžtas.
PASTABA: Apibrėžta active_support/core_ext/class/attribute.rb
.
4.1.2 cattr_reader
, cattr_writer
ir cattr_accessor
Makro cattr_reader
, cattr_writer
ir cattr_accessor
yra analogiški savo attr_*
atitikmenims, bet skirti klasėms. Jie inicializuoja klasės kintamąjį į nil
, jei jis dar neegzistuoja, ir generuoja atitinkamus klasės metodus, skirtus jį pasiekti:
class MysqlAdapter < AbstractAdapter
# Generuoja klasės metodus, skirtus pasiekti @@emulate_booleans.
cattr_accessor :emulate_booleans
end
Taip pat, galite perduoti bloką cattr_*
, kad nustatytumėte atributą su numatyta reikšme:
class MysqlAdapter < AbstractAdapter
# Generuoja klasės metodus, skirtus pasiekti @@emulate_booleans su numatyta reikšme true.
cattr_accessor :emulate_booleans, default: true
end
Taip pat yra sukuriami egzemplioriaus metodai patogumui, jie yra tiesiog peržiūros į klasės atributą. Taigi, egzemplioriai gali keisti klasės atributą, bet negali jį perrašyti, kaip tai atsitinka su class_attribute
(žr. aukščiau). Pavyzdžiui, turint
module ActionView
class Base
cattr_accessor :field_error_proc, default: Proc.new { ... }
end
end
mes galime pasiekti field_error_proc
per peržiūras.
Skaitymo egzemplioriaus metodo generavimą galima išvengti nustatant :instance_reader
į false
, o rašymo egzemplioriaus metodo generavimą galima išvengti nustatant :instance_writer
į false
. Abu metodai gali būti išvengti nustatant :instance_accessor
į false
. Visais atvejais reikšmė turi būti tiksliai false
, o ne bet kokia klaidinga reikšmė.
module A
class B
# Nebus sugeneruotas first_name egzemplioriaus skaitytuvas.
cattr_accessor :first_name, instance_reader: false
# Nebus sugeneruotas last_name= egzemplioriaus rašytojas.
cattr_accessor :last_name, instance_writer: false
# Nebus sugeneruotas surname egzemplioriaus skaitytuvas arba surname= rašytojas.
cattr_accessor :surname, instance_accessor: false
end
end
Modeliui gali būti naudinga nustatyti :instance_accessor
į false
kaip būdą užkirsti kelią masiniam priskyrimui nustatyti atributą.
PASTABA: Apibrėžta active_support/core_ext/module/attribute_accessors.rb
.
4.2 Subklasės ir palikuonys
4.2.1 subclasses
Metodas subclasses
grąžina gavėjo subklases:
class C; end
C.subclasses # => []
class B < C; end
C.subclasses # => [B]
class A < B; end
C.subclasses # => [B]
class D < C; end
C.subclasses # => [B, D]
Nenurodoma, kokia tvarka šios klasės yra grąžinamos.
PASTABA: Apibrėžta active_support/core_ext/class/subclasses.rb
.
4.2.2 descendants
Metodas descendants
grąžina visas klases, kurios yra <
nei gavėjas:
class C; end
C.descendants # => []
class B < C; end
C.descendants # => [B]
class A < B; end
C.descendants # => [B, A]
class D < C; end
C.descendants # => [B, A, D]
Nenurodoma, kokia tvarka šios klasės yra grąžinamos.
PASTABA: Apibrėžta active_support/core_ext/class/subclasses.rb
.
5 Plėtiniai String
5.1 Išvesties saugumas
5.1.1 Motyvacija
Duomenų įterpimas į HTML šablonus reikalauja papildomos priežiūros. Pavyzdžiui, negalite tiesiog įterpti @review.title
į HTML puslapį. Vienas dalykas, jei apžvalgos pavadinimas yra "Flanagan & Matz rules!", išvestis nebus gerai suformuota, nes ampersandas turi būti pakeisti į "&". Be to, priklausomai nuo programos, tai gali būti didelė saugumo spraga, nes vartotojai gali įterpti kenksmingą HTML, nustatydami rankų darbo apžvalgos pavadinimą. Daugiau informacijos apie rizikas dėl tarp svetainių skriptų galite rasti Saugumo vadove.
5.1.2 Saugūs eilutės
Active Support turi sąvoką (html) saugios eilutės. Saugi eilutė yra žymima kaip įterpiama į HTML be jokio pakeitimo. Ji yra patikima, nepriklausomai nuo to, ar ji buvo išvengta ar ne.
Pagal nutylėjimą eilutės laikomos nesaugiomis:
"".html_safe? # => false
Galite gauti saugią eilutę iš esamos naudodami html_safe
metodą:
s = "".html_safe
s.html_safe? # => true
Svarbu suprasti, kad html_safe
nevykdo jokio išvengimo, tai tik patvirtinimas:
s = "<script>...</script>".html_safe
s.html_safe? # => true
s # => "<script>...</script>"
Jūsų atsakomybė užtikrinti, kad html_safe
būtų tinkamai naudojamas tam tikroje eilutėje.
Jei pridedate prie saugios eilutės, arba vietiniu būdu naudojant concat
/<<
, arba su +
, rezultatas yra saugi eilutė. Nesaugūs argumentai yra išvengiami:
"".html_safe + "<" # => "<"
Saugūs argumentai yra tiesiog pridedami:
"".html_safe + "<".html_safe # => "<"
Šių metodų neturėtumėte naudoti įprastose peržiūrose. Nesaugios reikšmės automatiškai yra išvengiamos:
<%= @review.title %> <%# gerai, išvengiama, jei reikia %>
Norėdami įterpti kažką tiesiogiai, naudokite raw
pagalbininką, o ne kviesdami html_safe
:
<%= raw @cms.current_template %> <%# įterpia @cms.current_template kaip yra %>
arba, ekvivalentiškai, naudokite <%==
:
<%== @cms.current_template %> <%# įterpia @cms.current_template kaip yra %>
raw
pagalbininkas jums kviečia html_safe
:
def raw(stringish)
stringish.to_s.html_safe
end
PASTABA: Apibrėžta active_support/core_ext/string/output_safety.rb
.
5.1.3 Transformacija
Taisyklės pagalba, išskyrus galbūt sujungimą, kaip paaiškinta aukščiau, bet koks metodas, kuris gali pakeisti eilutę, suteikia jums nesaugią eilutę. Tai yra downcase
, gsub
, strip
, chomp
, underscore
, ir kt.
Atveju, kai vietinio pakeitimo, pvz., gsub!
, gavėjas pats tampa nesaugus.
INFORMACIJA: Saugumo bitas visada yra prarandamas, nepriklausomai nuo to, ar pakeitimas iš tikrųjų kažką pakeitė.
5.1.4 Konversija ir koercija
Kviečiant to_s
ant saugios eilutės grąžinama saugi eilutė, bet koercija su to_str
grąžina nesaugią eilutę.
5.1.5 Kopijavimas
Kviečiant dup
arba clone
ant saugių eilučių gaunamos saugios eilutės.
5.2 remove
Metodas remove
pašalins visus šablonus:
"Hello World".remove(/Hello /) # => "World"
Taip pat yra destruktyvi versija String#remove!
.
PASTABA: Apibrėžta active_support/core_ext/string/filters.rb
.
5.3 squish
Metodas squish
pašalina pradines ir galines tarpus, ir pakeičia tarpus su vienu tarpeliu:
" \n foo\n\r \t bar \n".squish # => "foo bar"
Taip pat yra destruktyvi versija String#squish!
.
Atkreipkite dėmesį, kad jis tvarko tiek ASCII, tiek Unikodo tarpus.
PASTABA: Apibrėžta active_support/core_ext/string/filters.rb
.
5.4 truncate
Metodas truncate
grąžina kopiją, kurios ilgis yra sumažintas iki nurodyto length
:
"Oh dear! Oh dear! I shall be late!".truncate(20)
# => "Oh dear! Oh dear!..."
Elipsė gali būti pritaikyta su :omission
parinktimi:
"Oh dear! Oh dear! I shall be late!".truncate(20, omission: '…')
# => "Oh dear! Oh …"
Ypač svarbu pastebėti, kad sutrumpinimas atsižvelgia į išvengimo eilutės ilgį.
Prašykite :separator
, kad sutrumpintumėte eilutę natūraliame pertraukime:
```ruby
"Oh dear! Oh dear! Aš pavėluosiu!".truncate(18)
=> "Oh dear! Oh dea..."
"Oh dear! Oh dear! Aš pavėluosiu!".truncate(18, separator: ' ')
=> "Oh dear! Oh..."
Parametras `:separator` gali būti reguliariosios išraiškos objektas:
```ruby
"Oh dear! Oh dear! Aš pavėluosiu!".truncate(18, separator: /\s/)
# => "Oh dear! Oh..."
Pirmuose pavyzdžiuose "dear" yra pjaunama pirmiausia, bet tada :separator
tai neleidžia.
PASTABA: Apibrėžta active_support/core_ext/string/filters.rb
.
5.5 truncate_bytes
Metodas truncate_bytes
grąžina kopiją savo gavėjo, sumažintą iki daugiausiai bytesize
baitų:
"👍👍👍👍".truncate_bytes(15)
# => "👍👍👍…"
Elipsė gali būti pritaikyta su :omission
parametru:
"👍👍👍👍".truncate_bytes(15, omission: "🖖")
# => "👍👍🖖"
PASTABA: Apibrėžta active_support/core_ext/string/filters.rb
.
5.6 truncate_words
Metodas truncate_words
grąžina kopiją savo gavėjo, sumažintą po tam tikro žodžių skaičiaus:
"Oh dear! Oh dear! Aš pavėluosiu!".truncate_words(4)
# => "Oh dear! Oh dear!..."
Elipsė gali būti pritaikyta su :omission
parametru:
"Oh dear! Oh dear! Aš pavėluosiu!".truncate_words(4, omission: '…')
# => "Oh dear! Oh dear!…"
Prašome perduoti :separator
, kad sutrumpintumėte eilutę natūraliame pertraukime:
"Oh dear! Oh dear! Aš pavėluosiu!".truncate_words(3, separator: '!')
# => "Oh dear! Oh dear! Aš pavėluosiu..."
Parametras :separator
gali būti reguliariosios išraiškos objektas:
"Oh dear! Oh dear! Aš pavėluosiu!".truncate_words(4, separator: /\s/)
# => "Oh dear! Oh dear!..."
PASTABA: Apibrėžta active_support/core_ext/string/filters.rb
.
5.7 inquiry
Metodas inquiry
konvertuoja eilutę į StringInquirer
objektą, padarant lygybės tikrinimą gražesnį.
"production".inquiry.production? # => true
"active".inquiry.inactive? # => false
PASTABA: Apibrėžta active_support/core_ext/string/inquiry.rb
.
5.8 starts_with?
ir ends_with?
Active Support apibrėžia 3-as asmenies sinonimus String#start_with?
ir String#end_with?
:
"foo".starts_with?("f") # => true
"foo".ends_with?("o") # => true
PASTABA: Apibrėžta active_support/core_ext/string/starts_ends_with.rb
.
5.9 strip_heredoc
Metodas strip_heredoc
pašalina įdėtą tekstą.
Pavyzdžiui:
if options[:usage]
puts <<-USAGE.strip_heredoc
This command does such and such.
Supported options are:
-h This message
...
USAGE
end
vartotojas matytų naudojimo pranešimą, išlygintą su kairiuoju kraštu.
Techniškai, jis ieško mažiausiai įdėtoje eilutėje visoje eilutėje ir pašalina tokio kiekio pradinius tuščius tarpus.
PASTABA: Apibrėžta active_support/core_ext/string/strip.rb
.
5.10 indent
Metodas indent
įtraukia eilutes gavėjui:
<<EOS.indent(2)
def some_method
some_code
end
EOS
# =>
def some_method
some_code
end
Antrasis argumentas, indent_string
, nurodo, kokį įtraukimo simbolį naudoti. Numatytoji reikšmė yra nil
, kuri nurodo metodui padaryti išsilavinimą, žiūrint į pirmą įdėtąją eilutę, ir jei jos nėra, naudoti tarpą.
" foo".indent(2) # => " foo"
"foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
"foo".indent(2, "\t") # => "\t\tfoo"
Nors indent_string
paprastai yra vienas tarpas ar tabuliacija, jis gali būti bet koks simbolis.
Trečiasis argumentas, indent_empty_lines
, yra žymeklis, kuris nurodo, ar tuščios eilutės turėtų būti įtrauktos. Numatytoji reikšmė yra false.
"foo\n\nbar".indent(2) # => " foo\n\n bar"
"foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar"
Metodas indent!
atlieka įtraukimą vietoje.
PASTABA: Apibrėžta active_support/core_ext/string/indent.rb
.
5.11 Prieiga
5.11.1 at(position)
at
metodas grąžina eilutės simbolį, esantį pozicijoje position
:
"hello".at(0) # => "h"
"hello".at(4) # => "o"
"hello".at(-1) # => "o"
"hello".at(10) # => nil
PASTABA: Apibrėžta active_support/core_ext/string/access.rb
faile.
5.11.2 from(position)
from
metodas grąžina eilutės dalį, pradedant nuo pozicijos position
:
"hello".from(0) # => "hello"
"hello".from(2) # => "llo"
"hello".from(-2) # => "lo"
"hello".from(10) # => nil
PASTABA: Apibrėžta active_support/core_ext/string/access.rb
faile.
5.11.3 to(position)
to
metodas grąžina eilutės dalį iki pozicijos position
:
"hello".to(0) # => "h"
"hello".to(2) # => "hel"
"hello".to(-2) # => "hell"
"hello".to(10) # => "hello"
PASTABA: Apibrėžta active_support/core_ext/string/access.rb
faile.
5.11.4 first(limit = 1)
first
metodas grąžina eilutės dalį, kuri sudaryta iš pirmųjų limit
simbolių.
Kviečiant str.first(n)
metodą, jei n
> 0, tai yra ekvivalentu str.to(n-1)
, o jei n
== 0, grąžinama tuščia eilutė.
PASTABA: Apibrėžta active_support/core_ext/string/access.rb
faile.
5.11.5 last(limit = 1)
last
metodas grąžina eilutės dalį, kuri sudaryta iš paskutinių limit
simbolių.
Kviečiant str.last(n)
metodą, jei n
> 0, tai yra ekvivalentu str.from(-n)
, o jei n
== 0, grąžinama tuščia eilutė.
PASTABA: Apibrėžta active_support/core_ext/string/access.rb
faile.
5.12 Linksniai
5.12.1 pluralize
pluralize
metodas grąžina savo argumento daugiskaitą:
"table".pluralize # => "tables"
"ruby".pluralize # => "rubies"
"equipment".pluralize # => "equipment"
Kaip rodo ankstesnis pavyzdys, Active Support žino keletą nereguliarių daugiskaitos formų ir neskaitomų daiktavardžių. Įdiegtos taisyklės gali būti išplėstos config/initializers/inflections.rb
faile. Šis failas pagal numatytuosius nustatymus yra generuojamas rails new
komandos ir turi instrukcijas komentarų pavidalu.
pluralize
metodas taip pat gali priimti pasirinktinį count
parametrą. Jei count == 1
, grąžinama vienaskaita forma. Kitais count
reikšmės atvejais grąžinama daugiskaita forma:
"dude".pluralize(0) # => "dudes"
"dude".pluralize(1) # => "dude"
"dude".pluralize(2) # => "dudes"
Active Record naudoja šį metodą, kad apskaičiuotų numatytąją lentelės pavadinimą, kuris atitinka modelį:
# active_record/model_schema.rb
def undecorated_table_name(model_name)
table_name = model_name.to_s.demodulize.underscore
pluralize_table_names ? table_name.pluralize : table_name
end
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
faile.
5.12.2 singularize
singularize
metodas yra pluralize
metodo atvirkštinė funkcija:
"tables".singularize # => "table"
"rubies".singularize # => "ruby"
"equipment".singularize # => "equipment"
Asociacijos naudoja šį metodą, kad apskaičiuotų atitinkamo numatomo susijusio klasės pavadinimą:
# active_record/reflection.rb
def derive_class_name
class_name = name.to_s.camelize
class_name = class_name.singularize if collection?
class_name
end
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
faile.
5.12.3 camelize
camelize
metodas grąžina savo argumentą camel case formato eilute:
"product".camelize # => "Product"
"admin_user".camelize # => "AdminUser"
Taisyklės pagalba galima manyti, kad šis metodas transformuoja kelius į Ruby klasės ar modulio pavadinimus, kur slash'ai atskiria vardų erdves:
"backoffice/session".camelize # => "Backoffice::Session"
Pavyzdžiui, Action Pack naudoja šį metodą, kad įkeltų klasę, kuri teikia tam tikrą sesijos saugyklą:
# action_controller/metal/session_management.rb
def session_store=(store)
@@session_store = store.is_a?(Symbol) ?
ActionDispatch::Session.const_get(store.to_s.camelize) :
store
end
camelize
metodas priima pasirinktinį argumentą, kuris gali būti :upper
(numatytasis) arba :lower
. Su paskutiniuoju mažinamas pirmasis raidė:
"visual_effect".camelize(:lower) # => "visualEffect"
Tai gali būti naudinga skaičiuoti metodų pavadinimus kalboje, kuri laikosi šios konvencijos, pavyzdžiui, JavaScript.
Taisyklės pagalba galite manyti, kad camelize
yra underscore
atvirkštinė funkcija, nors yra atvejų, kai tai netaikoma: "SSLError".underscore.camelize
grąžina "SslError"
. Norint palaikyti tokias situacijas, Active Support leidžia nurodyti akronimus config/initializers/inflections.rb
:
ActiveSupport::Inflector.inflections do |inflect|
inflect.acronym 'SSL'
end
"SSLError".underscore.camelize # => "SSLError"
camelize
yra sinonimas camelcase
.
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.4 underscore
Metodas underscore
veikia atvirkščiai, iš camel case pavadinimų gaunant kelius:
"Product".underscore # => "product"
"AdminUser".underscore # => "admin_user"
Taip pat pakeičia "::" į "/":
"Backoffice::Session".underscore # => "backoffice/session"
ir supranta mažąsias raides pradžioje:
"visualEffect".underscore # => "visual_effect"
underscore
nepriima jokių argumentų.
Rails naudoja underscore
gauti mažąsias raides kontrolerio klasėms:
# actionpack/lib/abstract_controller/base.rb
def controller_path
@controller_path ||= name.delete_suffix("Controller").underscore
end
Pavyzdžiui, ši reikšmė yra ta, kurią gaunate params[:controller]
.
Taisyklės pagalba galite manyti, kad underscore
yra camelize
atvirkštinė funkcija, nors yra atvejų, kai tai netaikoma. Pavyzdžiui, "SSLError".underscore.camelize
grąžina "SslError"
.
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.5 titleize
Metodas titleize
didina raides gavėjo žodyje:
"alice in wonderland".titleize # => "Alice In Wonderland"
"fermat's enigma".titleize # => "Fermat's Enigma"
titleize
yra sinonimas titlecase
.
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.6 dasherize
Metodas dasherize
pakeičia pabraukimus gavėjo brūkšneliais:
"name".dasherize # => "name"
"contact_data".dasherize # => "contact-data"
Modelių XML serijizatorius naudoja šį metodą, kad pakeistų mazgų pavadinimus brūkšneliais:
# active_model/serializers/xml.rb
def reformat_name(name)
name = name.camelize if camelize?
dasherize? ? name.dasherize : name
end
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.7 demodulize
Duodamas eilutės su kvalifikuotu konstantos pavadinimu, demodulize
grąžina tikrą konstantos pavadinimą, t. y. dešinįjį jos dalį:
"Product".demodulize # => "Product"
"Backoffice::UsersController".demodulize # => "UsersController"
"Admin::Hotel::ReservationUtils".demodulize # => "ReservationUtils"
"::Inflections".demodulize # => "Inflections"
"".demodulize # => ""
Pavyzdžiui, Active Record naudoja šį metodą, kad apskaičiuotų counter cache stulpelio pavadinimą:
# active_record/reflection.rb
def counter_cache_column
if options[:counter_cache] == true
"#{active_record.name.demodulize.underscore.pluralize}_count"
elsif options[:counter_cache]
options[:counter_cache]
end
end
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.8 deconstantize
Duodamas eilutės su kvalifikuota konstantos nuoroda, deconstantize
pašalina dešinę dalį, paliekant konstantos konteinerio pavadinimą:
"Product".deconstantize # => ""
"Backoffice::UsersController".deconstantize # => "Backoffice"
"Admin::Hotel::ReservationUtils".deconstantize # => "Admin::Hotel"
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.9 parameterize
Metodas parameterize
normalizuoja gavėją taip, kad jį būtų galima naudoti gražiuose URL.
"John Smith".parameterize # => "john-smith"
"Kurt Gödel".parameterize # => "kurt-godel"
Norint išlaikyti eilutės raidžių dydį, nustatykite preserve_case
argumentą į true. Pagal nutylėjimą, preserve_case
yra nustatytas į false.
"John Smith".parameterize(preserve_case: true) # => "John-Smith"
"Kurt Gödel".parameterize(preserve_case: true) # => "Kurt-Godel"
Norint naudoti pasirinktinį skyriklį, pakeiskite separator
argumentą.
"John Smith".parameterize(separator: "_") # => "john_smith"
"Kurt Gödel".parameterize(separator: "_") # => "kurt_godel"
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.10 tableize
Metodas tableize
yra underscore
sekantis pluralize
.
"Person".tableize # => "people"
"Invoice".tableize # => "invoices"
"InvoiceLine".tableize # => "invoice_lines"
Taisyklės pagalba, tableize
grąžina lentelės pavadinimą, kuris atitinka duotą modelį paprastais atvejais. Tikra implementacija Active Record nėra tiesiog tableize
, nes ji taip pat demodulizuoja klasės pavadinimą ir patikrina kelias parinktis, kurios gali paveikti grąžinamą eilutę.
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.11 classify
Metodas classify
yra tableize
atvirkštinis metodas. Jis grąžina klasės pavadinimą, kuris atitinka lentelės pavadinimą:
"people".classify # => "Person"
"invoices".classify # => "Invoice"
"invoice_lines".classify # => "InvoiceLine"
Metodas supranta kvalifikuotus lentelės pavadinimus:
"highrise_production.companies".classify # => "Company"
Atkreipkite dėmesį, kad classify
grąžina klasės pavadinimą kaip eilutę. Galite gauti faktinį klasės objektą, iškviesdami constantize
ant jo, kaip paaiškinta toliau.
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.12 constantize
Metodas constantize
išsprendžia konstantos nuorodos išraišką savo gavėjui:
"Integer".constantize # => Integer
module M
X = 1
end
"M::X".constantize # => 1
Jeigu eilutė neišsiskiria į jokią žinomą konstantą ar jos turinys neteisingas konstantos pavadinimas, constantize
iškelia NameError
.
Konstantos pavadinimo išsprendimas pagal constantize
visada prasideda nuo viršutinio lygio Object
, net jei nėra pirminio "::".
X = :in_Object
module M
X = :in_M
X # => :in_M
"::X".constantize # => :in_Object
"X".constantize # => :in_Object (!)
end
Taigi, tai apskritai nėra ekvivalentu tam, ką Ruby darytų tame pačiame taške, jei būtų įvertinta tikra konstanta.
Pašto testavimo atvejai gauna testuojamą paštą iš testo klasės pavadinimo naudodami constantize
:
# action_mailer/test_case.rb
def determine_default_mailer(name)
name.delete_suffix("Test").constantize
rescue NameError => e
raise NonInferrableMailerError.new(name)
end
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.13 humanize
Metodas humanize
keičia atributo pavadinimą, kad jis būtų tinkamas rodyti galutiniam vartotojui.
Konkrečiai, jis atlieka šiuos keitimus:
- Taiko žmogiškus linksniavimo taisykles argumentui.
- Pašalina pradinius pabraukimus, jei tokie yra.
- Pašalina "_id" priesagą, jei tokia yra.
- Pakeičia pabraukimus tarp žodžių tarpu, jei tokie yra.
- Mažina visus žodžius, išskyrus akronimus.
- Didina pirmąjį žodį.
Pirmojo žodžio didinimas gali būti išjungtas nustatant :capitalize
parinktį į false
(pagal nutylėjimą true
).
"name".humanize # => "Name"
"author_id".humanize # => "Author"
"author_id".humanize(capitalize: false) # => "author"
"comments_count".humanize # => "Comments count"
"_id".humanize # => "Id"
Jei "SSL" būtų apibrėžtas kaip akronimas:
'ssl_error'.humanize # => "SSL error"
Pagalbinis metodas full_messages
naudoja humanize
kaip atsarginę galimybę įtraukti atributo pavadinimus:
def full_messages
map { |attribute, message| full_message(attribute, message) }
end
def full_message
# ...
attr_name = attribute.to_s.tr('.', '_').humanize
attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
# ...
end
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.14 foreign_key
Metodas foreign_key
iš klasės pavadinimo suteikia svetimos rakto stulpelio pavadinimą. Tam jis demodulizuoja, pabraukia ir prideda "_id":
"User".foreign_key # => "user_id"
"InvoiceLine".foreign_key # => "invoice_line_id"
"Admin::Session".foreign_key # => "session_id"
Pereikškite klaidingą argumentą, jei nenorite pabraukti "_id":
"User".foreign_key(false) # => "userid"
Asociacijos naudoja šią metodą, kad nustatytų užsienio raktus, pavyzdžiui, has_one
ir has_many
tai daro:
# active_record/associations.rb
foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.15 upcase_first
Metodas upcase_first
didina pirmąjį simbolį:
"employee salary".upcase_first # => "Employee salary"
"".upcase_first # => ""
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.12.16 downcase_first
Metodas downcase_first
paverčia pirmąjį simbolį mažosiomis raidėmis:
"If I had read Alice in Wonderland".downcase_first # => "if I had read Alice in Wonderland"
"".downcase_first # => ""
PASTABA: Apibrėžta active_support/core_ext/string/inflections.rb
.
5.13 Konversijos
5.13.1 to_date
, to_time
, to_datetime
Metodai to_date
, to_time
ir to_datetime
yra praktiški apvalkalai aplink Date._parse
:
"2010-07-27".to_date # => Tue, 27 Jul 2010
"2010-07-27 23:37:00".to_time # => 2010-07-27 23:37:00 +0200
"2010-07-27 23:37:00".to_datetime # => Tue, 27 Jul 2010 23:37:00 +0000
to_time
priima pasirenkamą argumentą :utc
arba :local
, nurodantį, kurią laiko juostą norite gauti:
"2010-07-27 23:42:00".to_time(:utc) # => 2010-07-27 23:42:00 UTC
"2010-07-27 23:42:00".to_time(:local) # => 2010-07-27 23:42:00 +0200
Numatytasis yra :local
.
Norėdami gauti daugiau informacijos, kreipkitės į Date._parse
dokumentaciją.
Visi trys grąžina nil
tuščiems gavėjams.
PASTABA: Apibrėžta active_support/core_ext/string/conversions.rb
.
6 Plėtiniai Symbol
tipo objektams
6.1 starts_with?
ir ends_with?
Active Support apibrėžia 3-as asmenies sinonimus Symbol#start_with?
ir Symbol#end_with?
:
:foo.starts_with?("f") # => true
:foo.ends_with?("o") # => true
PASTABA: Apibrėžta active_support/core_ext/symbol/starts_ends_with.rb
.
7 Plėtiniai Numeric
tipo objektams
7.1 Baitai
Visi skaičiai atsako į šiuos metodus:
Jie grąžina atitinkamą baitų kiekį, naudodami konversijos faktorių 1024:
2.kilobytes # => 2048
3.megabytes # => 3145728
3.5.gigabytes # => 3758096384.0
-4.exabytes # => -4611686018427387904
Vienaskaitos formos yra sinonimai, todėl galite sakyti:
1.megabyte # => 1048576
PASTABA: Apibrėžta active_support/core_ext/numeric/bytes.rb
.
7.2 Laikas
Šie metodai:
leidžia deklaruoti ir skaičiuoti laiką, pvz., 45.minutes + 2.hours + 4.weeks
. Jų grąžinamos reikšmės taip pat gali būti pridėtos arba atimtos nuo laiko objektų.
Šiuos metodus galima derinti su from_now
, ago
ir kt., norint gauti tikslų datų skaičiavimą. Pavyzdžiui:
# ekvivalentu Time.current.advance(days: 1)
1.day.from_now
# ekvivalentu Time.current.advance(weeks: 2)
2.weeks.from_now
# ekvivalentu Time.current.advance(days: 4, weeks: 5)
(4.days + 5.weeks).from_now
ĮSPĖJIMAS. Kitoms trukmėms, prašome kreiptis į Integer
laiko plėtinius.
PASTABA: Apibrėžta active_support/core_ext/numeric/time.rb
.
7.3 Formatavimas
Leidžia formatuoti skaičius įvairiais būdais.
Gauti skaičiaus simbolių eilutės atitikmenį kaip telefono numerį:
5551234.to_fs(:phone)
# => 555-1234
1235551234.to_fs(:phone)
# => 123-555-1234
1235551234.to_fs(:phone, area_code: true)
# => (123) 555-1234
1235551234.to_fs(:phone, delimiter: " ")
# => 123 555 1234
1235551234.to_fs(:phone, area_code: true, extension: 555)
# => (123) 555-1234 x 555
1235551234.to_fs(:phone, country_code: 1)
# => +1-123-555-1234
Gauti skaičiaus simbolių eilutės atitikmenį kaip valiutą:
1234567890.50.to_fs(:currency) # => $1,234,567,890.50
1234567890.506.to_fs(:currency) # => $1,234,567,890.51
1234567890.506.to_fs(:currency, precision: 3) # => $1,234,567,890.506
Sukurkite skaičiaus eilutinį atvaizdavimą kaip procentą:
100.to_fs(:percentage)
# => 100.000%
100.to_fs(:percentage, precision: 0)
# => 100%
1000.to_fs(:percentage, delimiter: '.', separator: ',')
# => 1.000,000%
302.24398923423.to_fs(:percentage, precision: 5)
# => 302.24399%
Sukurkite skaičiaus eilutinį atvaizdavimą su skirtukais:
12345678.to_fs(:delimited) # => 12,345,678
12345678.05.to_fs(:delimited) # => 12,345,678.05
12345678.to_fs(:delimited, delimiter: ".") # => 12.345.678
12345678.to_fs(:delimited, delimiter: ",") # => 12,345,678
12345678.05.to_fs(:delimited, separator: " ") # => 12,345,678 05
Sukurkite skaičiaus eilutinį atvaizdavimą su apvalinimu:
111.2345.to_fs(:rounded) # => 111.235
111.2345.to_fs(:rounded, precision: 2) # => 111.23
13.to_fs(:rounded, precision: 5) # => 13.00000
389.32314.to_fs(:rounded, precision: 0) # => 389
111.2345.to_fs(:rounded, significant: true) # => 111
Sukurkite skaičiaus eilutinį atvaizdavimą kaip skaitytino baitų skaičiaus:
123.to_fs(:human_size) # => 123 Baitai
1234.to_fs(:human_size) # => 1.21 KB
12345.to_fs(:human_size) # => 12.1 KB
1234567.to_fs(:human_size) # => 1.18 MB
1234567890.to_fs(:human_size) # => 1.15 GB
1234567890123.to_fs(:human_size) # => 1.12 TB
1234567890123456.to_fs(:human_size) # => 1.1 PB
1234567890123456789.to_fs(:human_size) # => 1.07 EB
Sukurkite skaičiaus eilutinį atvaizdavimą kaip skaitytino žodžiais:
123.to_fs(:human) # => "123"
1234.to_fs(:human) # => "1.23 Tūkstantis"
12345.to_fs(:human) # => "12.3 Tūkstantis"
1234567.to_fs(:human) # => "1.23 Milijonas"
1234567890.to_fs(:human) # => "1.23 Milijardas"
1234567890123.to_fs(:human) # => "1.23 Trilijonas"
1234567890123456.to_fs(:human) # => "1.23 Kvadrilijonas"
Pastaba: Apibrėžta active_support/core_ext/numeric/conversions.rb
.
8 Plėtiniai Integer
tipui
8.1 multiple_of?
Metodas multiple_of?
patikrina, ar sveikasis skaičius yra argumento daugiklis:
2.multiple_of?(1) # => true
1.multiple_of?(2) # => false
Pastaba: Apibrėžta active_support/core_ext/integer/multiple.rb
.
8.2 ordinal
Metodas ordinal
grąžina eilutę su skaitmeniu ir atitinkančiu priesaga:
1.ordinal # => "st"
2.ordinal # => "nd"
53.ordinal # => "rd"
2009.ordinal # => "th"
-21.ordinal # => "st"
-134.ordinal # => "th"
Pastaba: Apibrėžta active_support/core_ext/integer/inflections.rb
.
8.3 ordinalize
Metodas ordinalize
grąžina eilutę su skaitmeniu ir atitinkančiu priesaga. Palyginimui, ordinal
metodas grąžina tik priesagos eilutę.
1.ordinalize # => "1st"
2.ordinalize # => "2nd"
53.ordinalize # => "53rd"
2009.ordinalize # => "2009th"
-21.ordinalize # => "-21st"
-134.ordinalize # => "-134th"
Pastaba: Apibrėžta active_support/core_ext/integer/inflections.rb
.
8.4 Laikas
Šie metodai:
leidžia deklaruoti ir skaičiuoti laiką, pvz., 4.months + 5.years
. Jų grąžinamos reikšmės taip pat gali būti pridėtos arba atimtos nuo laiko objektų.
Šiuos metodus galima derinti su from_now
, ago
ir pan., siekiant tikslaus datos skaičiavimo. Pavyzdžiui:
# ekvivalentu Time.current.advance(months: 1)
1.month.from_now
# ekvivalentu Time.current.advance(years: 2)
2.years.from_now
# ekvivalentu Time.current.advance(months: 4, years: 5)
(4.months + 5.years).from_now
ĮSPĖJIMAS. Kitoms trukmėms kreipkitės į Numeric
laiko plėtinius.
Pastaba: Apibrėžta active_support/core_ext/integer/time.rb
.
9 Plėtiniai BigDecimal
tipui
9.1 to_s
Metodas to_s
numatytuoju parametru naudoja "F" formatą. Tai reiškia, kad paprastas to_s
iškvietimas grąžins slankiojo kablelio atvaizdavimą, o ne inžinerinį įrašą:
BigDecimal(5.00, 6).to_s # => "5.0"
Vis dar galima naudoti inžinerinį įrašą:
BigDecimal(5.00, 6).to_s("e") # => "0.5E1"
10 Plėtiniai Enumerable
tipui
10.1 sum
Metodas sum
sudeda elementus iš eilės:
ruby
[1, 2, 3].sum # => 6
(1..100).sum # => 5050
Sudėtis priima tik elementus, kurie gali atlikti veiksmą +
:
[[1, 2], [2, 3], [3, 4]].sum # => [1, 2, 2, 3, 3, 4]
%w(foo bar baz).sum # => "foobarbaz"
{ a: 1, b: 2, c: 3 }.sum # => [:a, 1, :b, 2, :c, 3]
Tuščios kolekcijos suma pagal nutylėjimą yra nulis, tačiau tai galima keisti:
[].sum # => 0
[].sum(1) # => 1
Jeigu yra pateiktas blokas, sum
tampa iteratoriumi, kuris grąžina kolekcijos elementus ir sudeda grąžintas reikšmes:
(1..5).sum { |n| n * 2 } # => 30
[2, 4, 6, 8, 10].sum # => 30
Tuščios gavėjo sumos taip pat galima keisti šioje formoje:
[].sum(1) { |n| n**3 } # => 1
PASTABA: Apibrėžta active_support/core_ext/enumerable.rb
.
10.2 index_by
Metodas index_by
sugeneruoja raktų ir reikšmių poras, kur raktai yra kažkokio raktinio žodžio pagal indeksą.
Jis peržiūri kolekciją ir perduoda kiekvieną elementą blokui. Elementas bus raktas, grąžintas bloko:
invoices.index_by(&:number)
# => {'2009-032' => <Invoice ...>, '2009-008' => <Invoice ...>, ...}
ĮSPĖJIMAS. Raktai paprastai turėtų būti unikalūs. Jei blokas grąžina tą pačią reikšmę skirtingiems elementams, tokiu atveju nebus sukurtas joks rinkinys šiam raktui. Laimi paskutinis elementas.
PASTABA: Apibrėžta active_support/core_ext/enumerable.rb
.
10.3 index_with
Metodas index_with
sugeneruoja raktų ir reikšmių poras, kur raktai yra kolekcijos elementai. Reikšmė
yra arba perduotas numatytasis arba grąžinamas bloke.
post = Post.new(title: "hey there", body: "what's up?")
%i( title body ).index_with { |attr_name| post.public_send(attr_name) }
# => { title: "hey there", body: "what's up?" }
WEEKDAYS.index_with(Interval.all_day)
# => { monday: [ 0, 1440 ], … }
PASTABA: Apibrėžta active_support/core_ext/enumerable.rb
.
10.4 many?
Metodas many?
yra trumpinys collection.size > 1
:
<% if pages.many? %>
<%= pagination_links %>
<% end %>
Jeigu yra pateiktas pasirinktinis blokas, many?
atsižvelgia tik į tuos elementus, kurie grąžina true
:
@see_more = videos.many? { |video| video.category == params[:category] }
PASTABA: Apibrėžta active_support/core_ext/enumerable.rb
.
10.5 exclude?
Predikatas exclude?
patikrina, ar duotas objektas ne priklauso kolekcijai. Tai yra įprasto include?
neigimas:
to_visit << node if visited.exclude?(node)
PASTABA: Apibrėžta active_support/core_ext/enumerable.rb
.
10.6 including
Metodas including
grąžina naują kolekciją, kuri įtraukia perduotus elementus:
[ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
["David", "Rafael"].including %w[ Aaron Todd ] # => ["David", "Rafael", "Aaron", "Todd"]
PASTABA: Apibrėžta active_support/core_ext/enumerable.rb
.
10.7 excluding
Metodas excluding
grąžina kopiją kolekcijos su pašalintais nurodytais elementais:
["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
excluding
yra sinonimas without
.
PASTABA: Apibrėžta active_support/core_ext/enumerable.rb
.
10.8 pluck
Metodas pluck
išskiria nurodytą raktą iš kiekvieno elemento:
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name) # => ["David", "Rafael", "Aaron"]
[{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name) # => [[1, "David"], [2, "Rafael"]]
PASTABA: Apibrėžta active_support/core_ext/enumerable.rb
.
10.9 pick
Metodas pick
ištraukia nurodytą raktą iš pirmojo elemento:
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pick(:name) # => "David"
[{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pick(:id, :name) # => [1, "David"]
PASTABA: Apibrėžta active_support/core_ext/enumerable.rb
.
11 Plėtiniai Array
11.1 Prieiga
Active Support papildo masyvų API, kad būtų lengviau pasiekti tam tikrus jų elementus. Pavyzdžiui, to
grąžina submasyvą, kuris apima elementus iki nurodyto indekso:
%w(a b c d).to(2) # => ["a", "b", "c"]
[].to(7) # => []
Panašiai, from
grąžina užpakalį nuo nurodyto indekso iki galo. Jei indeksas yra didesnis nei masyvo ilgis, grąžinamas tuščias masyvas.
%w(a b c d).from(2) # => ["c", "d"]
%w(a b c d).from(10) # => []
[].from(0) # => []
Metodas including
grąžina naują masyvą, kuriame yra nurodyti elementai:
[ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
[ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
Metodas excluding
grąžina kopiją masyvo, išskyrus nurodytus elementus.
Tai yra Enumerable#excluding
optimizacija, kuri naudoja Array#-
vietoje Array#reject
dėl našumo priežasčių.
["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
[ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
Metodai second
, third
, fourth
ir fifth
grąžina atitinkamą elementą, taip pat second_to_last
ir third_to_last
(first
ir last
yra įdiegti). Dėka socialinio išmintingumo ir teigiamo konstruktyvumo visur, forty_two
taip pat yra prieinamas.
%w(a b c d).third # => "c"
%w(a b c d).fifth # => nil
PASTABA: Apibrėžta active_support/core_ext/array/access.rb
.
11.2 Ištraukimas
Metodas extract!
pašalina ir grąžina elementus, kuriems blokas grąžina teisingą reikšmę.
Jei nėra nurodytas blokas, grąžinamas vietoj to yra Enumeratorius.
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
numbers # => [0, 2, 4, 6, 8]
PASTABA: Apibrėžta active_support/core_ext/array/extract.rb
.
11.3 Parinkčių ištraukimas
Kai paskutinis argumentas metodo iškvietime yra hash'as, išskyrus galbūt &block
argumentą, Ruby leidžia jums praleisti skliaustus:
User.exists?(email: params[:email])
Toks sintaksinis cukrus dažnai naudojamas Rails'e, kad būtų išvengta pozicinių argumentų, kai jų būtų per daug, o vietoj to siūlomi sąsajos, kurios imituoja vardinius parametrus. Ypač idiomatiška yra naudoti užbaigtinį hash'ą parinktims.
Jei metodas tikisi kintamo skaičiaus argumentų ir jo deklaracijoje naudoja *
, tokiame parinkčių hash'as tampa argumentų masyvo elementu, kur jis praranda savo vaidmenį.
Tokiu atveju galite suteikti parinkčių hash'ui išskirtinį apdorojimą naudodami extract_options!
. Šis metodas patikrina masyvo paskutinio elemento tipą. Jei tai yra hash'as, jis išimamas ir grąžinamas, kitu atveju grąžinamas tuščias hash'as.
Pavyzdžiui, pažvelkime į caches_action
valdiklio makro apibrėžimą:
def caches_action(*actions)
return unless cache_configured?
options = actions.extract_options!
# ...
end
Šis metodas priima bet kokį veiksmo pavadinimų skaičių ir pasirinktiną raktų hash'ą kaip paskutinį argumentą. Iškvietus extract_options!
gaunate raktų hash'ą ir pašalinamas iš actions
paprastu ir aiškiu būdu.
PASTABA: Apibrėžta active_support/core_ext/array/extract_options.rb
.
11.4 Konvertavimai
11.4.1 to_sentence
Metodas to_sentence
paverčia masyvą į eilutę, kurioje išvardijami jo elementai:
%w().to_sentence # => ""
%w(Earth).to_sentence # => "Earth"
%w(Earth Wind).to_sentence # => "Earth and Wind"
%w(Earth Wind Fire).to_sentence # => "Earth, Wind, and Fire"
Šis metodas priima tris pasirinktinius parametrus:
:two_words_connector
: Naudojama masyvams, turintiems 2 elementus. Numatytasis yra " and ".:words_connector
: Naudojama sujungti masyvo elementus, turinčius 3 ar daugiau elementų, išskyrus paskutinius du. Numatytasis yra ", ".:last_word_connector
: Naudojama sujungti paskutinius masyvo elementus, turinčius 3 ar daugiau elementų. Numatytasis yra ", and ".
Šių parametrų numatytieji nustatymai gali būti lokalizuoti, jų raktai yra:
Parametras | I18n raktas |
---|---|
:two_words_connector |
support.array.two_words_connector |
:words_connector |
support.array.words_connector |
:last_word_connector |
support.array.last_word_connector |
PASTABA: Apibrėžta active_support/core_ext/array/conversions.rb
.
11.4.2 to_fs
Metodas to_fs
pagal numatytuosius nustatymus veikia kaip to_s
.
Tačiau, jei masyvas turi elementus, kurie gali atsakyti į id
, simbolis
:db
gali būti perduotas kaip argumentas. Tai dažnai naudojama su
Active Record objektų kolekcijomis. Grąžinamos eilutės yra:
[].to_fs(:db) # => "null"
[user].to_fs(:db) # => "8456"
invoice.lines.to_fs(:db) # => "23,567,556,12"
Pavyzdžio aukščiau esantys sveikieji skaičiai turėtų būti gauti iš atitinkamų id
iškvietimų.
PASTABA: Apibrėžta active_support/core_ext/array/conversions.rb
.
11.4.3 to_xml
Metodas to_xml
grąžina eilutę, kuri yra jo gavėjo XML atvaizdavimas:
Contributor.limit(2).order(:rank).to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <contributors type="array">
# <contributor>
# <id type="integer">4356</id>
# <name>Jeremy Kemper</name>
# <rank type="integer">1</rank>
# <url-id>jeremy-kemper</url-id>
# </contributor>
# <contributor>
# <id type="integer">4404</id>
# <name>David Heinemeier Hansson</name>
# <rank type="integer">2</rank>
# <url-id>david-heinemeier-hansson</url-id>
# </contributor>
# </contributors>
Tam jis išsiunčia to_xml
kiekvienam elementui iš eilės ir surinkia rezultatus po šakniniu mazgu. Visi elementai turi atsakyti į to_xml
, kitu atveju iškeliama išimtis.
Numatytasis šakninio elemento pavadinimas yra pirmojo elemento klasės pavadinimo su pabraukimu ir brūkšneliu daugiskaita, jei likusieji elementai priklauso tam pačiam tipui (patikrinama su is_a?
) ir jie nėra hash'ai. Pavyzdyje aukščiau tai yra "contributors".
Jei yra bent vienas elementas, kuris nepriklauso pirmojo elemento tipui, šakninis mazgas tampa "objects":
[Contributor.first, Commit.first].to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <objects type="array">
# <object>
# <id type="integer">4583</id>
# <name>Aaron Batalion</name>
# <rank type="integer">53</rank>
# <url-id>aaron-batalion</url-id>
# </object>
# <object>
# <author>Joshua Peek</author>
# <authored-timestamp type="datetime">2009-09-02T16:44:36Z</authored-timestamp>
# <branch>origin/master</branch>
# <committed-timestamp type="datetime">2009-09-02T16:44:36Z</committed-timestamp>
# <committer>Joshua Peek</committer>
# <git-show nil="true"></git-show>
# <id type="integer">190316</id>
# <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>
# </object>
# </objects>
Jei gavėjas yra maišų masyvas, pagrindinis elementas pagal numatytuosius nustatymus taip pat yra "objects":
[{ a: 1, b: 2 }, { c: 3 }].to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <objects type="array">
# <object>
# <b type="integer">2</b>
# <a type="integer">1</a>
# </object>
# <object>
# <c type="integer">3</c>
# </object>
# </objects>
ĮSPĖJIMAS. Jei kolekcija yra tuščia, pagal numatytuosius nustatymus pagrindinis elementas yra "nil-classes". Tai yra gudrybė, pavyzdžiui, aukščiau pateikto kontributorių sąrašo pagrindinis elementas nebūtų "contributors", jei kolekcija būtų tuščia, bet "nil-classes". Galite naudoti :root
parinktį, kad būtų užtikrintas nuoseklus pagrindinis elementas.
Vaikų mazgų pavadinimas pagal numatytuosius nustatymus yra pagrindinio mazgo pavadinimas vienaskaita. Aukščiau pateiktuose pavyzdžiuose matėme "contributor" ir "object". :children
parinktis leidžia nustatyti šiuos mazgų pavadinimus.
Numatytasis XML kūrėjas yra naujas Builder::XmlMarkup
egzempliorius. Galite konfigūruoti savo kūrėją per :builder
parinktį. Metodas taip pat priima parinktis, pvz., :dasherize
ir kt., kurios perduodamos kūrėjui:
Contributor.limit(2).order(:rank).to_xml(skip_types: true)
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <contributors>
# <contributor>
# <id>4356</id>
# <name>Jeremy Kemper</name>
# <rank>1</rank>
# <url-id>jeremy-kemper</url-id>
# </contributor>
# <contributor>
# <id>4404</id>
# <name>David Heinemeier Hansson</name>
# <rank>2</rank>
# <url-id>david-heinemeier-hansson</url-id>
# </contributor>
# </contributors>
PASTABA: Apibrėžta active_support/core_ext/array/conversions.rb
.
11.5 Apvyniojimas
Metodas Array.wrap
apvynioja savo argumentą į masyvą, nebent jis jau yra masyvas (arba panašus į masyvą).
Konkrečiai:
- Jei argumentas yra
nil
, grąžinamas tuščias masyvas. - Kitu atveju, jei argumentas gali būti iššauktas
to_ary
, jis iššaukiamas, ir jeito_ary
grąžinimo reikšmė nėranil
, ji grąžinama. - Kitu atveju, grąžinamas masyvas su argumentu kaip vieninteliu elementu.
Array.wrap(nil) # => []
Array.wrap([1, 2, 3]) # => [1, 2, 3]
Array.wrap(0) # => [0]
Šis metodas panašus į Kernel#Array
tikslais, tačiau yra kai kurie skirtumai:
- Jei argumentas gali būti iššauktas
to_ary
, metodas yra iššaukiamas.Kernel#Array
tęsia bandymą iššauktito_a
, jei grąžinta reikšmė yranil
, betArray.wrap
iš karto grąžina masyvą su argumentu kaip vieninteliu elementu. - Jei grąžinta reikšmė iš
to_ary
nėra neinil
, neiArray
objektas,Kernel#Array
iškelia išimtį, oArray.wrap
to nedaro, ji tiesiog grąžina reikšmę. - Jei argumentas neatsako į
to_ary
, ji nekviečiato_a
ir grąžina masyvą su argumentu kaip vieninteliu elementu.
Ypač verta palyginti paskutinį punktą kai kuriems išvardijimams:
Array.wrap(foo: :bar) # => [{:foo=>:bar}]
Array(foo: :bar) # => [[:foo, :bar]]
Taip pat yra susijusi idiomatika, kuri naudoja splat operatorių:
[*object]
PASTABA: Apibrėžta active_support/core_ext/array/wrap.rb
.
11.6 Kopijavimas
Metodas Array#deep_dup
dubliuoja save ir visus objektus viduje
rekursyviai su Active Support metodu Object#deep_dup
. Tai veikia kaip Array#map
, siunčiant deep_dup
metodą kiekvienam objektui viduje.
array = [1, [2, 3]]
dup = array.deep_dup
dup[1][2] = 4
array[1][2] == nil # => true
PASTABA: Apibrėžta active_support/core_ext/object/deep_dup.rb
.
11.7 Grupavimas
11.7.1 in_groups_of(skaičius, užpildyti = nil)
Metodas in_groups_of
padalina masyvą į nuoseklius grupes, kurių dydis yra nurodytas. Jis grąžina masyvą su grupėmis:
[1, 2, 3].in_groups_of(2) # => [[1, 2], [3, nil]]
arba perduoda jas vieną po kito, jei perduodamas blokas:
<% sample.in_groups_of(3) do |a, b, c| %>
<tr>
<td><%= a %></td>
<td><%= b %></td>
<td><%= c %></td>
</tr>
<% end %>
Pirmas pavyzdys parodo, kaip in_groups_of
užpildo paskutinę grupę tiek nil
elementais, kiek reikia, kad būtų pasiektas pageidaujamas dydis. Galite pakeisti šį užpildymo reikšmę naudodami antrąjį pasirinktinį argumentą:
[1, 2, 3].in_groups_of(2, 0) # => [[1, 2], [3, 0]]
Ir galite pasakyti metodui, kad paskutinė grupė neturi būti užpildyta, perduodant false
:
[1, 2, 3].in_groups_of(2, false) # => [[1, 2], [3]]
Dėl to false
negali būti naudojama kaip užpildymo reikšmė.
PASTABA: Apibrėžta active_support/core_ext/array/grouping.rb
.
11.7.2 in_groups(skaičius, užpildyti = nil)
Metodas in_groups
padalina masyvą į tam tikrą grupių skaičių. Metodas grąžina masyvą su grupėmis:
%w(1 2 3 4 5 6 7).in_groups(3)
# => [["1", "2", "3"], ["4", "5", nil], ["6", "7", nil]]
arba perduoda jas vieną po kito, jei perduodamas blokas:
%w(1 2 3 4 5 6 7).in_groups(3) { |group| p group }
["1", "2", "3"]
["4", "5", nil]
["6", "7", nil]
Aukščiau pateikti pavyzdžiai rodo, kad in_groups
užpildo kai kurias grupes papildomu nil
elementu, jei reikia. Grupė gali gauti ne daugiau kaip vieną šio papildomo elemento, jei toks yra. Ir grupės, kuriose jie yra, visada yra paskutinės.
Galite pakeisti šią užpildymo reikšmę naudodami antrąjį pasirinktinį argumentą:
%w(1 2 3 4 5 6 7).in_groups(3, "0")
# => [["1", "2", "3"], ["4", "5", "0"], ["6", "7", "0"]]
Ir galite pasakyti metodui, kad mažesnės grupės neturi būti užpildytos, perduodant false
:
%w(1 2 3 4 5 6 7).in_groups(3, false)
# => [["1", "2", "3"], ["4", "5"], ["6", "7"]]
Dėl to false
negali būti naudojama kaip užpildymo reikšmė.
PASTABA: Apibrėžta active_support/core_ext/array/grouping.rb
.
11.7.3 split(reikšmė = nil)
Metodas split
padalina masyvą pagal skyriklį ir grąžina rezultatą.
Jei perduodamas blokas, skyrikliai yra tie masyvo elementai, kuriems blokas grąžina true
:
(-5..5).to_a.split { |i| i.multiple_of?(4) }
# => [[-5], [-3, -2, -1], [1, 2, 3], [5]]
Kitu atveju, argumentas, kuris pagal nutylėjimą yra nil
, yra skyriklis:
[0, 1, -5, 1, 1, "foo", "bar"].split(1)
# => [[0], [-5], [], ["foo", "bar"]]
PATARIMAS: Pastebėkite ankstesniame pavyzdyje, kad iš eilės esantys skyrikliai rezultuoja tuščius masyvus.
PASTABA: Apibrėžta active_support/core_ext/array/grouping.rb
.
12 Plėtiniai Hash
tipo objektui
12.1 Konversijos
12.1.1 to_xml
Metodas to_xml
grąžina eilutę, kurią sudaro jo gavėjo XML reprezentacija:
{ foo: 1, bar: 2 }.to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <hash>
# <foo type="integer">1</foo>
# <bar type="integer">2</bar>
# </hash>
Tam, kad tai padarytumėte, metodas kartojasi per poras ir sukuria priklausomas nuo reikšmių mazgas. Turint porą key
, value
:
Jei
value
yra hash, vykdomas rekursinis kvietimas sukey
kaip:root
.Jei
value
yra masyvas, vykdomas rekursinis kvietimas sukey
kaip:root
, irkey
vienaskaitinė forma kaip:children
.Jei
value
yra kviečiamas objektas, jis turi tikėtis vieno ar dviejų argumentų. Priklausomai nuo argumentų skaičiaus, kviečiamas objektas yra iškviečiamas suoptions
hash kaip pirmu argumentu sukey
kaip:root
, irkey
vienaskaitinė forma kaip antru argumentu. Jo grąžinimo reikšmė tampa nauju mazgu.Jei
value
atsako įto_xml
, kviečiamas metodas sukey
kaip:root
.Kitu atveju, sukuriamas mazgas su
key
kaip žyma irvalue
teksto mazgu kaip jo teksto reprezentacija. Jeivalue
yranil
, pridedamas atributas "nil" su reikšme "true". Jei neegzistuoja:skip_types
parinktis ir ji yra true, taip pat pridedamas atributas "type" pagal šią sąrašą:
XML_TYPE_NAMES = {
"Symbol" => "symbol",
"Integer" => "integer",
"BigDecimal" => "decimal",
"Float" => "float",
"TrueClass" => "boolean",
"FalseClass" => "boolean",
"Date" => "date",
"DateTime" => "datetime",
"Time" => "datetime"
}
Pagal numatytuosius nustatymus šakninis mazgas yra "hash", bet tai galima konfigūruoti naudojant :root
parinktį.
Numatytasis XML kūrėjas yra naujas Builder::XmlMarkup
objekto egzempliorius. Galite konfigūruoti savo kūrėją naudojant :builder
parinktį. Metodas taip pat priima parinktis, pvz., :dasherize
ir kt., kurios perduodamos kūrėjui.
PASTABA: Apibrėžta active_support/core_ext/hash/conversions.rb
faile.
12.2 Sujungimas
Ruby turi įmontuotą Hash#merge
metodą, kuris sujungia du hash'us:
{ a: 1, b: 1 }.merge(a: 0, c: 2)
# => {:a=>0, :b=>1, :c=>2}
Active Support apibrėžia keletą papildomų būdų, kaip sujungti hash'us, kas gali būti patogu.
12.2.1 reverse_merge
ir reverse_merge!
Atveju, kai įvyksta susidūrimas, merge
metode laimi argumento hash'o raktas. Galite palaikyti parinkčių hash'us su numatytosiomis reikšmėmis kompaktiškai naudodami šią idiomą:
options = { length: 30, omission: "..." }.merge(options)
Active Support apibrėžia reverse_merge
atveju, jei pageidaujate šios alternatyvios sintaksės:
options = options.reverse_merge(length: 30, omission: "...")
Taip pat yra bang versija reverse_merge!
, kuri atlieka sujungimą vietoje:
options.reverse_merge!(length: 30, omission: "...")
ĮSPĖJIMAS. Atkreipkite dėmesį, kad reverse_merge!
gali pakeisti hash'ą iškvietėjoje, kas gali būti gera arba ne.
PASTABA: Apibrėžta active_support/core_ext/hash/reverse_merge.rb
faile.
12.2.2 reverse_update
Metodas reverse_update
yra sinonimas reverse_merge!
, kuris buvo paaiškintas aukščiau.
ĮSPĖJIMAS. Atkreipkite dėmesį, kad reverse_update
neturi bang simbolio.
PASTABA: Apibrėžta active_support/core_ext/hash/reverse_merge.rb
faile.
12.2.3 deep_merge
ir deep_merge!
Kaip matote ankstesniame pavyzdyje, jei raktas yra rastas abiejuose hash'uose, reikšmė iš argumento hash'o laimi.
Active Support apibrėžia Hash#deep_merge
. Gilyn sujungiant, jei raktas yra rastas abiejuose hash'uose ir jų reikšmės yra vėl hash'ai, tada jų sujungimas tampa rezultuojančio hash'o reikšme:
{ a: { b: 1 } }.deep_merge(a: { c: 2 })
# => {:a=>{:b=>1, :c=>2}}
Metodas deep_merge!
atlieka gilų sujungimą vietoje.
PASTABA: Apibrėžta active_support/core_ext/hash/deep_merge.rb
.
12.3 Gilus kopijavimas
Metodas Hash#deep_dup
dubliuoja save ir visus raktus bei reikšmes
rekursyviai naudojant Active Support metodo Object#deep_dup
. Jis veikia kaip Enumerator#each_with_object
, siunčiant deep_dup
metodą kiekvienam porai viduje.
hash = { a: 1, b: { c: 2, d: [3, 4] } }
dup = hash.deep_dup
dup[:b][:e] = 5
dup[:b][:d] << 5
hash[:b][:e] == nil # => true
hash[:b][:d] == [3, 4] # => true
PASTABA: Apibrėžta active_support/core_ext/object/deep_dup.rb
.
12.4 Darbas su raktų
12.4.1 except
ir except!
Metodas except
grąžina raktus, esančius argumentų sąraše, pašalintus iš hash, jei jie yra:
{ a: 1, b: 2 }.except(:a) # => {:b=>2}
Jei gavėjas atsako į convert_key
, metodas yra iškviestas kiekvienam iš argumentų. Tai leidžia except
gerai veikti su hash, kuris turi abejotiną prieigą, pavyzdžiui:
{ a: 1 }.with_indifferent_access.except(:a) # => {}
{ a: 1 }.with_indifferent_access.except("a") # => {}
Taip pat yra bang variantas except!
, kuris pašalina raktus vietoje.
PASTABA: Apibrėžta active_support/core_ext/hash/except.rb
.
12.4.2 stringify_keys
ir stringify_keys!
Metodas stringify_keys
grąžina hash, kuriame yra raktų, esančių gavėjui, sustringifikuota versija. Tai daroma siunčiant jiems to_s
:
{ nil => nil, 1 => 1, a: :a }.stringify_keys
# => {"" => nil, "1" => 1, "a" => :a}
Atveju, kai yra raktų susidūrimas, reikšmė bus naujausia įterpta į hash:
{ "a" => 1, a: 2 }.stringify_keys
# Rezultatas bus
# => {"a"=>2}
Šis metodas gali būti naudingas, pavyzdžiui, lengvai priimti tiek simbolius, tiek eilutes kaip parinktis. Pavyzdžiui, ActionView::Helpers::FormHelper
apibrėžia:
def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0")
options = options.stringify_keys
options["type"] = "checkbox"
# ...
end
Antra eilutė saugiai gali pasiekti "type" raktą ir leisti vartotojui perduoti :type
arba "type".
Taip pat yra bang variantas stringify_keys!
, kuris vietoje sustringifikuoti raktus.
Be to, galima naudoti deep_stringify_keys
ir deep_stringify_keys!
, kad sustringifikuotumėte visus raktus duotame hashe ir visuose jame įdėtuose hashuose. Pavyzdys rezultato yra:
{ nil => nil, 1 => 1, nested: { a: 3, 5 => 5 } }.deep_stringify_keys
# => {""=>nil, "1"=>1, "nested"=>{"a"=>3, "5"=>5}}
PASTABA: Apibrėžta active_support/core_ext/hash/keys.rb
.
12.4.3 symbolize_keys
ir symbolize_keys!
Metodas symbolize_keys
grąžina hash, kuriame yra simbolizuota raktų versija gavėjui, kai tai įmanoma. Tai daroma siunčiant jiems to_sym
:
{ nil => nil, 1 => 1, "a" => "a" }.symbolize_keys
# => {nil=>nil, 1=>1, :a=>"a"}
ĮSPĖJIMAS. Pastaba, kad ankstesniame pavyzdyje buvo simbolizuotas tik vienas raktas.
Atveju, kai yra raktų susidūrimas, reikšmė bus naujausia įterpta į hash:
{ "a" => 1, a: 2 }.symbolize_keys
# => {:a=>2}
Šis metodas gali būti naudingas, pavyzdžiui, lengvai priimti tiek simbolius, tiek eilutes kaip parinktis. Pavyzdžiui, ActionText::TagHelper
apibrėžia
```ruby
def rich_text_area_tag(name, value = nil, options = {})
options = options.symbolize_keys
options[:input] ||= "trix_input_#{ActionText::TagHelper.id += 1}" # ... end ```
Trečioji eilutė saugiai gali pasiekti :input
raktą ir leisti vartotojui perduoti tiek :input
, tiek "input".
Taip pat yra bang variantas symbolize_keys!
, kuris simbolizuoja raktus vietoje.
Be to, galima naudoti deep_symbolize_keys
ir deep_symbolize_keys!
, kad simbolizuotumėte visus raktus duotame haeše ir visuose jame įdėtuose haešuose. Pavyzdys rezultato yra:
{ nil => nil, 1 => 1, "nested" => { "a" => 3, 5 => 5 } }.deep_symbolize_keys
# => {nil=>nil, 1=>1, nested:{a:3, 5=>5}}
PASTABA: Apibrėžta active_support/core_ext/hash/keys.rb
.
12.4.4 to_options
ir to_options!
Metodai to_options
ir to_options!
yra symbolize_keys
ir symbolize_keys!
sinonimai, atitinkamai.
PASTABA: Apibrėžta active_support/core_ext/hash/keys.rb
.
12.4.5 assert_valid_keys
Metodas assert_valid_keys
priima bet kokį skaičių argumentų ir patikrina, ar gavėjas neturi jokių raktų, kurie nėra išvardyti. Jei taip, išmetamas ArgumentError
.
{ a: 1 }.assert_valid_keys(:a) # praeina
{ a: 1 }.assert_valid_keys("a") # ArgumentError
Active Record nepriima nežinomų parinkčių, kuriant asociacijas, pavyzdžiui. Jis įgyvendina šią kontrolę naudodamas assert_valid_keys
.
PASTABA: Apibrėžta active_support/core_ext/hash/keys.rb
.
12.5 Darbas su reikšmėmis
12.5.1 deep_transform_values
ir deep_transform_values!
Metodas deep_transform_values
grąžina naują haešą, kuriame visos reikšmės konvertuojamos naudojant bloko operaciją. Tai apima reikšmes iš pagrindinio haešo ir visų įdėtų haešų ir masyvų.
hash = { person: { name: 'Rob', age: '28' } }
hash.deep_transform_values { |value| value.to_s.upcase }
# => {person: {name: "ROB", age: "28"}}
Taip pat yra bang variantas deep_transform_values!
, kuris sunaikina visus reikšmes, naudodamas bloko operaciją.
PASTABA: Apibrėžta active_support/core_ext/hash/deep_transform_values.rb
.
12.6 Pjovimas
Metodas slice!
pakeičia haešą tik su duotais raktais ir grąžina haešą, kuriame yra pašalinti raktų ir reikšmių poros.
hash = { a: 1, b: 2 }
rest = hash.slice!(:a) # => {:b=>2}
hash # => {:a=>1}
PASTABA: Apibrėžta active_support/core_ext/hash/slice.rb
.
12.7 Ištraukimas
Metodas extract!
pašalina ir grąžina raktų ir reikšmių poras, atitinkančias duotus raktus.
hash = { a: 1, b: 2 }
rest = hash.extract!(:a) # => {:a=>1}
hash # => {:b=>2}
Metodas extract!
grąžina tą pačią Hash
klasės subklasę, kuri yra gavėjas.
hash = { a: 1, b: 2 }.with_indifferent_access
rest = hash.extract!(:a).class
# => ActiveSupport::HashWithIndifferentAccess
PASTABA: Apibrėžta active_support/core_ext/hash/slice.rb
.
12.8 Nesvarbus prieiga
Metodas with_indifferent_access
grąžina ActiveSupport::HashWithIndifferentAccess
iš savo gavėjo:
{ a: 1 }.with_indifferent_access["a"] # => 1
PASTABA: Apibrėžta active_support/core_ext/hash/indifferent_access.rb
.
13 Plėtiniai Regexp
13.1 multiline?
Metodas multiline?
nurodo, ar reguliariam išraiškai yra nustatytas /m
vėliavėlė, tai yra, ar taškas atitinka naujas eilutes.
%r{.}.multiline? # => false
%r{.}m.multiline? # => true
Regexp.new('.').multiline? # => false
Regexp.new('.', Regexp::MULTILINE).multiline? # => true
Rails naudoja šį metodą tik vienoje vietoje, taip pat maršrutizavimo kode. Daugeilinės reguliariosios išraiškos maršrutams yra draudžiamos, ir ši vėliavėlė palengvina šio apribojimo taikymą.
def verify_regexp_requirements(requirements)
# ...
if requirement.multiline?
raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{requirement.inspect}"
end
# ...
end
PASTABA: Apibrėžta active_support/core_ext/regexp.rb
.
14 Plėtiniai Range
14.1 to_fs
Active Support apibrėžia Range#to_fs
kaip alternatyvą to_s
, kuri supranta pasirinktinį formato argumentą. Šiuo metu palaikomas tik neprivalomas formatas :db
:
(Date.today..Date.tomorrow).to_fs
# => "2009-10-25..2009-10-26"
(Date.today..Date.tomorrow).to_fs(:db)
# => "BETWEEN '2009-10-25' AND '2009-10-26'"
Kaip pavyzdys iliustruoja, :db
formatas generuoja BETWEEN
SQL sąlygą. Tai naudojama Active Record, palaikant intervalo reikšmes sąlygose.
PASTABA: Apibrėžta active_support/core_ext/range/conversions.rb
.
14.2 ===
ir include?
Metodai Range#===
ir Range#include?
nurodo, ar tam tikra reikšmė patenka tarp duotų intervalo galų:
(2..3).include?(Math::E) # => true
Active Support išplečia šiuos metodus, kad argumentas galėtų būti kitas intervalas. Tokiu atveju tikriname, ar argumento intervalo galai priklauso pačiam intervalui:
(1..10) === (3..7) # => true
(1..10) === (0..7) # => false
(1..10) === (3..11) # => false
(1...9) === (3..9) # => false
(1..10).include?(3..7) # => true
(1..10).include?(0..7) # => false
(1..10).include?(3..11) # => false
(1...9).include?(3..9) # => false
PASTABA: Apibrėžta active_support/core_ext/range/compare_range.rb
.
14.3 overlap?
Metodas Range#overlap?
nurodo, ar duotiems intervalams yra ne tuščias sankirta:
(1..10).overlap?(7..11) # => true
(1..10).overlap?(0..7) # => true
(1..10).overlap?(11..27) # => false
PASTABA: Apibrėžta active_support/core_ext/range/overlap.rb
.
15 Plėtiniai Date
15.1 Skaičiavimai
Šie skaičiavimo metodai turi ribines sąlygas 1582 m. spalio mėnesį, nes dienos nuo 5 iki 14 tiesiog neegzistuoja. Šiame vadove jų elgsenos aplink tas dienas nėra aprašyta dėl trumpumo, tačiau pakanka pasakyti, kad jie daro tai, ko tikėtumėte. Tai reiškia, kad Date.new(1582, 10, 4).tomorrow
grąžina Date.new(1582, 10, 15)
ir taip toliau. Norėdami sužinoti tikėtiną elgseną, patikrinkite test/core_ext/date_ext_test.rb
Active Support testų rinkinyje.
15.1.1 Date.current
Active Support apibrėžia Date.current
kaip šiandienos datą dabarties laiko juostoje. Tai panašu į Date.today
, tačiau jis gerbia vartotojo laiko juostą, jei ji nustatyta. Taip pat apibrėžia Date.yesterday
ir Date.tomorrow
, taip pat past?
, today?
, tomorrow?
, next_day?
, yesterday?
, prev_day?
, future?
, on_weekday?
ir on_weekend?
, visi jie yra susiję su Date.current
.
Lyginant datas naudojant metodus, kurie gerbia vartotojo laiko juostą, įsitikinkite, kad naudojate Date.current
, o ne Date.today
. Yra atvejų, kai vartotojo laiko juosta gali būti ateityje, palyginti su sistemos laiko juosta, kurią pagal nutylėjimą naudoja Date.today
. Tai reiškia, kad Date.today
gali būti lygus Date.yesterday
.
PASTABA: Apibrėžta active_support/core_ext/date/calculations.rb
.
15.1.2 Pavadinimai datoms
15.1.2.1 beginning_of_week
, end_of_week
Metodai beginning_of_week
ir end_of_week
grąžina savaitės pradžios ir pabaigos datą atitinkamai. Savaitės pradžia priklauso nuo pirmadienio, bet tai gali būti pakeista perduodant argumentą, nustatant gijos vietinį Date.beginning_of_week
arba config.beginning_of_week
.
d = Date.new(2010, 5, 8) # => Sat, 08 May 2010
d.beginning_of_week # => Mon, 03 May 2010
d.beginning_of_week(:sunday) # => Sun, 02 May 2010
d.end_of_week # => Sun, 09 May 2010
d.end_of_week(:sunday) # => Sat, 08 May 2010
beginning_of_week
yra sinonimas at_beginning_of_week
ir end_of_week
yra sinonimas at_end_of_week
.
PASTABA: Apibrėžta active_support/core_ext/date_and_time/calculations.rb
.
15.1.2.2 monday
, sunday
Metodai monday
ir sunday
grąžina ankstesnį pirmadienį ir kitą sekmadienį atitinkamai.
ruby
date = Date.new(2010, 6, 7)
date.months_ago(3) # => Thu, 07 Mar 2010
date.months_since(3) # => Mon, 07 Sep 2010
If such a day does not exist, the last day of the corresponding month is returned:
Date.new(2012, 3, 31).months_ago(1) # => Thu, 29 Feb 2012
Date.new(2012, 1, 31).months_since(1) # => Wed, 29 Feb 2012
last_month
is short-hand for #months_ago(1)
.
15.1.2.3 weeks_ago
, weeks_since
The methods weeks_ago
and [weeks_since
][DateAndTime::Calculations#weeks_since] work analogously for weeks:
date = Date.new(2010, 6, 7)
date.weeks_ago(2) # => Mon, 24 May 2010
date.weeks_since(2) # => Mon, 21 Jun 2010
last_week
is short-hand for #weeks_ago(1)
.
15.1.2.4 days_ago
, days_since
The methods [days_ago
][DateAndTime::Calculations#days_ago] and [days_since
][DateAndTime::Calculations#days_since] work analogously for days:
date = Date.new(2010, 6, 7)
date.days_ago(5) # => Wed, 02 Jun 2010
date.days_since(5) # => Sat, 12 Jun 2010
[yesterday
][DateAndTime::Calculations#yesterday] is short-hand for #days_ago(1)
, and [tomorrow
][DateAndTime::Calculations#tomorrow] is short-hand for #days_since(1)
.
Jei tokios dienos nėra, grąžinamas atitinkamo mėnesio paskutinė diena:
Date.new(2010, 4, 30).months_ago(2) # => Sek, 28 Vas 2010
Date.new(2009, 12, 31).months_since(2) # => Sek, 28 Vas 2010
last_month
yra trumpinys #months_ago(1)
.
PASTABA: Apibrėžta active_support/core_ext/date_and_time/calculations.rb
.
15.1.2.5 weeks_ago
Metodas weeks_ago
veikia analogiškai savaitėms:
Date.new(2010, 5, 24).weeks_ago(1) # => Pirm, 17 Geg 2010
Date.new(2010, 5, 24).weeks_ago(2) # => Pirm, 10 Geg 2010
PASTABA: Apibrėžta active_support/core_ext/date_and_time/calculations.rb
.
15.1.2.6 advance
Bendriausias būdas pereiti prie kitų dienų yra advance
. Šis metodas priima maišą su raktiniais žodžiais :years
, :months
, :weeks
, :days
, ir grąžina datą, kuri yra tiek pat priekyje, kiek nurodyti raktiniai žodžiai:
date = Date.new(2010, 6, 6)
date.advance(years: 1, weeks: 2) # => Pirm, 20 Bir 2011
date.advance(months: 2, days: -2) # => Tre, 04 Rgp 2010
Pastaba, kad padidinimai gali būti neigiami.
PASTABA: Apibrėžta active_support/core_ext/date/calculations.rb
.
15.1.3 Komponentų keitimas
Metodas change
leidžia gauti naują datą, kuri yra tokia pati kaip gavėjas, išskyrus nurodytus metus, mėnesį ar dieną:
Date.new(2010, 12, 23).change(year: 2011, month: 11)
# => Tre, 23 Lap 2011
Šis metodas netoleruoja neegzistuojančių datų, jei keitimas yra netinkamas, išmetamas ArgumentError
:
Date.new(2010, 1, 31).change(month: 2)
# => ArgumentError: negaliojanti data
PASTABA: Apibrėžta active_support/core_ext/date/calculations.rb
.
15.1.4 Trukmės
Prie datų galima pridėti arba iš jų atimti Duration
objektus:
d = Date.current
# => Pirm, 09 Rgp 2010
d + 1.year
# => Antr, 09 Rgp 2011
d - 3.hours
# => Sek, 08 Rgp 2010 21:00:00 UTC +00:00
Jie verčiami į kvietimus since
arba advance
. Pavyzdžiui, čia gauname teisingą peršokimą kalendoriaus reformoje:
Date.new(1582, 10, 4) + 1.day
# => Pen, 15 Spa 1582
15.1.5 Laiko žymos
Jei įmanoma, šie metodai grąžina Time
objektą, kitu atveju - DateTime
. Jei nustatyta, jie gerbia vartotojo laiko juostą.
15.1.5.1 beginning_of_day
, end_of_day
Metodas beginning_of_day
grąžina laiko žymą dienos pradžioje (00:00:00):
date = Date.new(2010, 6, 7)
date.beginning_of_day # => Pirm Jun 07 00:00:00 +0200 2010
Metodas end_of_day
grąžina laiko žymą dienos pabaigoje (23:59:59):
date = Date.new(2010, 6, 7)
date.end_of_day # => Pirm Jun 07 23:59:59 +0200 2010
beginning_of_day
yra sinonimas at_beginning_of_day
, midnight
, at_midnight
.
PASTABA: Apibrėžta active_support/core_ext/date/calculations.rb
.
15.1.5.2 beginning_of_hour
, end_of_hour
Metodas beginning_of_hour
grąžina laiko žymą valandos pradžioje (hh:00:00):
date = DateTime.new(2010, 6, 7, 19, 55, 25)
date.beginning_of_hour # => Pirm Jun 07 19:00:00 +0200 2010
Metodas end_of_hour
grąžina laiko žymą valandos pabaigoje (hh:59:59):
date = DateTime.new(2010, 6, 7, 19, 55, 25)
date.end_of_hour # => Pirm Jun 07 19:59:59 +0200 2010
beginning_of_hour
yra sinonimas at_beginning_of_hour
.
PASTABA: Apibrėžta active_support/core_ext/date_time/calculations.rb
.
15.1.5.3 beginning_of_minute
, end_of_minute
Metodas beginning_of_minute
grąžina laiko žymą minutės pradžioje (hh:mm:00):
ruby
date = DateTime.new(2010, 6, 7, 19, 55, 25)
date.beginning_of_minute # => Pirmadienis, birželio 07 19:55:00 +0200 2010
Metodas end_of_minute
grąžina laiko žymą minutės pabaigoje (hh:mm:59):
date = DateTime.new(2010, 6, 7, 19, 55, 25)
date.end_of_minute # => Pirmadienis, birželio 07 19:55:59 +0200 2010
beginning_of_minute
yra sinonimas at_beginning_of_minute
.
beginning_of_hour
, end_of_hour
, beginning_of_minute
ir end_of_minute
yra įgyvendinti Time
ir DateTime
, bet ne Date
, nes neturi prasmės prašyti valandos ar minutės pradžios ar pabaigos Date
egzemplioriuje.
PASTABA: Apibrėžta active_support/core_ext/date_time/calculations.rb
.
15.1.5.4 ago
, since
Metodas ago
priima sekundžių skaičių kaip argumentą ir grąžina laiko žymą tiek sekundžių atgal nuo vidurnakčio:
date = Date.current # => Penktadienis, birželio 11 2010
date.ago(1) # => Ketvirtadienis, birželio 10 2010 23:59:59 EDT -04:00
Panašiai, since
juda į priekį:
date = Date.current # => Penktadienis, birželio 11 2010
date.since(1) # => Penktadienis, birželio 11 2010 00:00:01 EDT -04:00
PASTABA: Apibrėžta active_support/core_ext/date/calculations.rb
.
16 Plėtiniai DateTime
ĮSPĖJIMAS: DateTime
nežino DST taisyklių, todėl kai kurie iš šių metodų turi ribinius atvejus, kai vyksta DST keitimas. Pavyzdžiui, seconds_since_midnight
gali negrąžinti tikro kiekio tokiame dieną.
16.1 Skaičiavimai
Klasė DateTime
yra Date
po-klasė, todėl įkelus active_support/core_ext/date/calculations.rb
paveldite šiuos metodus ir jų sinonimus, išskyrus tai, kad jie visada grąžins datetimes.
Šie metodai yra įgyvendinti, todėl nereikia įkelti active_support/core_ext/date/calculations.rb
šiems:
Kita vertus, advance
ir change
taip pat yra apibrėžti ir palaiko daugiau parinkčių, jie yra aprašyti žemiau.
Šie metodai yra įgyvendinti tik active_support/core_ext/date_time/calculations.rb
, nes jie turi prasmę tik naudojant DateTime
egzempliorių:
16.1.1 Pavadinimai laikui
16.1.1.1 DateTime.current
Active Support apibrėžia DateTime.current
būti kaip Time.now.to_datetime
, išskyrus tai, kad jis gerbia vartotojo laiko juostą, jei apibrėžta. Egzemplioriaus predikatai past?
ir future?
yra apibrėžti atsižvelgiant į DateTime.current
.
PASTABA: Apibrėžta active_support/core_ext/date_time/calculations.rb
.
16.1.2 Kiti plėtiniai
16.1.2.1 seconds_since_midnight
Metodas seconds_since_midnight
grąžina sekundžių skaičių nuo vidurnakčio:
now = DateTime.current # => Pirmadienis, birželio 07 2010 20:26:36 +0000
now.seconds_since_midnight # => 73596
PASTABA: Apibrėžta active_support/core_ext/date_time/calculations.rb
.
16.1.2.2 utc
Metodas utc
suteikia jums tą patį datetime gavėjo išreikštą UTC laiku.
now = DateTime.current # => Pirmadienis, birželio 07 2010 19:27:52 -0400
now.utc # => Pirmadienis, birželio 07 2010 23:27:52 +0000
Šis metodas taip pat yra sinonimas getutc
.
PASTABA: Apibrėžta active_support/core_ext/date_time/calculations.rb
.
16.1.2.3 utc?
Predikatas utc?
sako, ar gavėjas turi UTC kaip laiko juostą:
now = DateTime.now # => Pirmadienis, birželio 07 2010 19:30:47 -0400
now.utc? # => false
now.utc.utc? # => true
PASTABA: Apibrėžta active_support/core_ext/date_time/calculations.rb
.
16.1.2.4 advance
Bendriausias būdas pereiti prie kito datetime yra advance
. Šis metodas priima maišą su raktiniais žodžiais :years
, :months
, :weeks
, :days
, :hours
, :minutes
ir :seconds
, ir grąžina datetime, pažengusį tiek, kiek dabartiniai raktai nurodo.
```ruby
d = DateTime.current
=> Ket, 05 Rugpjūtis 2010 11:33:31 +0000
d.advance(years: 1, months: 1, days: 1, hours: 1, minutes: 1, seconds: 1)
=> An, 06 Rugsėjis 2011 12:34:32 +0000
Ši metodas pirmiausia apskaičiuoja paskirties datą, perduodamas `:years`, `:months`, `:weeks` ir `:days` į `Date#advance`, kuris yra aprašytas aukščiau. Po to, jis sureguliuoja laiką, iškviesdamas [`since`][DateTime#since] su sekundžių skaičiumi, kurį reikia pridėti. Ši tvarka yra svarbi, kita tvarka duotų skirtingas datos ir laiko reikšmes kai kuriuose ribiniuose atvejuose. Pavyzdys `Date#advance` taikomas ir galime jį išplėsti, kad parodytume tvarkos svarbą, susijusią su laiko elementais.
Jei pirmiausia perkeltume datos elementus (kurie taip pat turi santykinę tvarką, kaip jau buvo aprašyta), o po to laiko elementus, gautume, pavyzdžiui, šią skaičiavimą:
```ruby
d = DateTime.new(2010, 2, 28, 23, 59, 59)
# => Sek, 28 Vasaris 2010 23:59:59 +0000
d.advance(months: 1, seconds: 1)
# => Pir, 29 Kovas 2010 00:00:00 +0000
bet jei juos apskaičiuotume kitaip, rezultatas būtų skirtingas:
d.advance(seconds: 1).advance(months: 1)
# => Ket, 01 Balandis 2010 00:00:00 +0000
ĮSPĖJIMAS: Kadangi DateTime
nėra DST informacijos turintis, galite patekti į neegzistuojančią laiko tašką be jokio įspėjimo ar klaidos pranešimo.
PASTABA: Apibrėžta active_support/core_ext/date_time/calculations.rb
.
16.1.3 Komponentų keitimas
Metodas change
leidžia gauti naują datą ir laiką, kuris yra tas pats kaip ir pradinis, išskyrus duotus parametrus, kurie gali apimti :year
, :month
, :day
, :hour
, :min
, :sec
, :offset
, :start
:
now = DateTime.current
# => An, 08 Birželis 2010 01:56:22 +0000
now.change(year: 2011, offset: Rational(-6, 24))
# => Tre, 08 Birželis 2011 01:56:22 -0600
Jei valandos yra nustatytos į nulį, tai taip pat taikoma minutėms ir sekundėms (jei jos neturi nustatytų reikšmių):
now.change(hour: 0)
# => An, 08 Birželis 2010 00:00:00 +0000
Panašiai, jei minutės yra nustatytos į nulį, tai taip pat taikoma sekundėms (jei jos neturi nustatytos reikšmės):
now.change(min: 0)
# => An, 08 Birželis 2010 01:00:00 +0000
Šis metodas netoleruoja neegzistuojančių datų, jei keitimas yra netinkamas, iškeliama ArgumentError
:
DateTime.current.change(month: 2, day: 30)
# => ArgumentError: negaliojanti data
PASTABA: Apibrėžta active_support/core_ext/date_time/calculations.rb
.
16.1.4 Trukmės
Duration
objektai gali būti pridėti arba atimti iš datų ir laikų:
now = DateTime.current
# => Pir, 09 Rugpjūtis 2010 23:15:17 +0000
now + 1.year
# => An, 09 Rugpjūtis 2011 23:15:17 +0000
now - 1.week
# => Pir, 02 Rugpjūtis 2010 23:15:17 +0000
Jie verčiami į since
arba advance
iškvietimus. Pavyzdžiui, čia gauname teisingą perėjimą kalendoriaus reformoje:
DateTime.new(1582, 10, 4, 23) + 1.hour
# => Pen, 15 Spalis 1582 00:00:00 +0000
17 Time
plėtinių
17.1 Skaičiavimai
Jie yra analogiški. Prašome kreiptis į jų dokumentaciją aukščiau ir atkreipti dėmesį į šias skirtumus:
change
priima papildomą:usec
parametrą.Time
supranta DST, todėl gaunate teisingus DST skaičiavimus, kaip šiuo atveju
Time.zone_default
# => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
# Barselonoje, 2010/03/28 02:00 +0100 tampa 2010/03/28 03:00 +0200 dėl DST.
t = Time.local(2010, 3, 28, 1, 59, 59)
# => Sek Mar 28 01:59:59 +0100 2010
t.advance(seconds: 1)
# => Sek Mar 28 03:00:00 +0200 2010
- Jei
since
arbaago
nukelia į laiką, kuris negali būti išreikštas suTime
, grąžinamasDateTime
objektas.
17.1.1 Time.current
Active Support apibrėžia Time.current
kaip šiandien esantį laiką dabartinėje laiko juostoje. Tai panašu į Time.now
, tačiau tai gerbia vartotojo laiko juostą, jei ji yra apibrėžta. Taip pat apibrėžiami past?
, today?
, tomorrow?
, next_day?
, yesterday?
, prev_day?
ir future?
metodai, visi jie susiję su Time.current
.
Lyginant laiką naudojant metodus, kurie gerbia vartotojo laiko juostą, įsitikinkite, kad naudojate Time.current
vietoje Time.now
. Yra atvejų, kai vartotojo laiko juosta gali būti ateityje, palyginti su sistemos laiko juosta, kurią pagal nutylėjimą naudoja Time.now
. Tai reiškia, kad Time.now.to_date
gali būti lygus Date.yesterday
.
PASTABA: Apibrėžta active_support/core_ext/time/calculations.rb
faile.
17.1.2 all_day
, all_week
, all_month
, all_quarter
ir all_year
Metodas all_day
grąžina intervalą, kuris atitinka visą šios dienos laiką.
now = Time.current
# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
now.all_day
# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Mon, 09 Aug 2010 23:59:59 UTC +00:00
Analogiškai, all_week
, all_month
, all_quarter
ir all_year
visi turi tikslą generuoti laiko intervalus.
now = Time.current
# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
now.all_week
# => Mon, 09 Aug 2010 00:00:00 UTC +00:00..Sun, 15 Aug 2010 23:59:59 UTC +00:00
now.all_week(:sunday)
# => Sun, 16 Sep 2012 00:00:00 UTC +00:00..Sat, 22 Sep 2012 23:59:59 UTC +00:00
now.all_month
# => Sat, 01 Aug 2010 00:00:00 UTC +00:00..Tue, 31 Aug 2010 23:59:59 UTC +00:00
now.all_quarter
# => Thu, 01 Jul 2010 00:00:00 UTC +00:00..Thu, 30 Sep 2010 23:59:59 UTC +00:00
now.all_year
# => Fri, 01 Jan 2010 00:00:00 UTC +00:00..Fri, 31 Dec 2010 23:59:59 UTC +00:00
PASTABA: Apibrėžta active_support/core_ext/date_and_time/calculations.rb
faile.
17.1.3 prev_day
, next_day
prev_day
ir next_day
grąžina laiką prieš tai arba po to esančią dieną:
t = Time.new(2010, 5, 8) # => 2010-05-08 00:00:00 +0900
t.prev_day # => 2010-05-07 00:00:00 +0900
t.next_day # => 2010-05-09 00:00:00 +0900
PASTABA: Apibrėžta active_support/core_ext/time/calculations.rb
faile.
17.1.4 prev_month
, next_month
prev_month
ir next_month
grąžina laiką su tuo pačiu dienos numeriu praėjusį arba ateinantį mėnesį:
t = Time.new(2010, 5, 8) # => 2010-05-08 00:00:00 +0900
t.prev_month # => 2010-04-08 00:00:00 +0900
t.next_month # => 2010-06-08 00:00:00 +0900
Jei tokios dienos nėra, grąžinamas atitinkamo mėnesio paskutinė diena:
Time.new(2000, 5, 31).prev_month # => 2000-04-30 00:00:00 +0900
Time.new(2000, 3, 31).prev_month # => 2000-02-29 00:00:00 +0900
Time.new(2000, 5, 31).next_month # => 2000-06-30 00:00:00 +0900
Time.new(2000, 1, 31).next_month # => 2000-02-29 00:00:00 +0900
PASTABA: Apibrėžta active_support/core_ext/time/calculations.rb
faile.
17.1.5 prev_year
, next_year
prev_year
ir next_year
grąžina laiką su tuo pačiu dienos/mėnesio numeriu praėjusiais arba ateinančiais metais:
t = Time.new(2010, 5, 8) # => 2010-05-08 00:00:00 +0900
t.prev_year # => 2009-05-08 00:00:00 +0900
t.next_year # => 2011-05-08 00:00:00 +0900
Jei data yra vasario 29 diena perkeliamaisiais metais, gaunate vasario 28 dieną:
t = Time.new(2000, 2, 29) # => 2000-02-29 00:00:00 +0900
t.prev_year # => 1999-02-28 00:00:00 +0900
t.next_year # => 2001-02-28 00:00:00 +0900
PASTABA: Apibrėžta faile active_support/core_ext/time/calculations.rb
.
17.1.6 prev_quarter
, next_quarter
prev_quarter
ir next_quarter
grąžina datą su tuo pačiu dienos numeriu ankstesniame arba kitame ketvirtyje:
t = Time.local(2010, 5, 8) # => 2010-05-08 00:00:00 +0300
t.prev_quarter # => 2010-02-08 00:00:00 +0200
t.next_quarter # => 2010-08-08 00:00:00 +0300
Jei tokios dienos nėra, grąžinamas atitinkamo mėnesio paskutinė diena:
Time.local(2000, 7, 31).prev_quarter # => 2000-04-30 00:00:00 +0300
Time.local(2000, 5, 31).prev_quarter # => 2000-02-29 00:00:00 +0200
Time.local(2000, 10, 31).prev_quarter # => 2000-07-31 00:00:00 +0300
Time.local(2000, 11, 31).next_quarter # => 2001-03-01 00:00:00 +0200
prev_quarter
yra sinonimas last_quarter
.
PASTABA: Apibrėžta faile active_support/core_ext/date_and_time/calculations.rb
.
17.2 Laiko konstruktorius
Active Support apibrėžia Time.current
kaip Time.zone.now
, jei yra apibrėžta vartotojo laiko juosta, ir kaip Time.now
, jei nėra:
Time.zone_default
# => #<ActiveSupport::TimeZone:0x7f73654d4f38 @utc_offset=nil, @name="Madrid", ...>
Time.current
# => Fri, 06 Aug 2010 17:11:58 CEST +02:00
Analogiškai DateTime
, past?
ir future?
predikatai yra susiję su Time.current
.
Jei konstruojamas laikas yra už ribų, kurias palaiko Time
vykdymo platforma, mikrosekundės yra atmestos ir grąžinamas DateTime
objektas.
17.2.1 Trukmės
Laikui galima pridėti ir iš jo atimti Duration
objektus:
now = Time.current
# => Mon, 09 Aug 2010 23:20:05 UTC +00:00
now + 1.year
# => Tue, 09 Aug 2011 23:21:11 UTC +00:00
now - 1.week
# => Mon, 02 Aug 2010 23:21:11 UTC +00:00
Jie verčiami į since
arba advance
kvietimus. Pavyzdžiui, čia gauname teisingą peršokimą kalendoriaus reformoje:
Time.utc(1582, 10, 3) + 5.days
# => Mon Oct 18 00:00:00 UTC 1582
18 File
plėtiniai
18.1 atomic_write
Naudojant klasės metodo File.atomic_write
galima įrašyti į failą taip, kad joks skaitytojas nematytų pusiau įrašyto turinio.
Failo pavadinimas perduodamas kaip argumentas, o metodas grąžina failo rankeną, atidarytą rašymui. Baigus vykdyti bloką, atomic_write
uždaro failo rankeną ir atlieka savo darbą.
Pavyzdžiui, Action Pack naudoja šį metodą, norėdama įrašyti turtų kašės failus, pvz., all.css
:
File.atomic_write(joined_asset_path) do |cache|
cache.write(join_asset_file_contents(asset_paths))
end
Tam atomic_write
sukuria laikiną failą. Tai yra failas, į kurį bloko kode iš tikrųjų rašoma. Baigus darbą, laikinas failas pervadinamas, kas POSIX sistemose yra atomiška operacija. Jei tikslinis failas egzistuoja, atomic_write
jį perrašo ir išlaiko savininkus ir teises. Tačiau yra keletas atvejų, kai atomic_write
negali pakeisti failo savininko ar teisių, ši klaida yra aptinkama ir praleidžiama, tikintis, kad vartotojas/operacinė sistema užtikrins, kad failas būtų pasiekiamas procesams, kurie jo reikia.
PASTABA. Dėl atomic_write
atliekamo chmod veiksmo, jei tiksliniame faile yra nustatytas ACL, šis ACL bus perskaičiuotas/modifikuotas.
ĮSPĖJIMAS. Atkreipkite dėmesį, kad negalima pridėti su atomic_write
.
Pagalbiniai failai rašomi į standartinį laikinų failų katalogą, bet galite perduoti jūsų pasirinktą katalogą kaip antrą argumentą.
PASTABA: Apibrėžta faile active_support/core_ext/file/atomic.rb
.
19 NameError
plėtiniai
Aktyvusis palaikymas prideda missing_name?
prie NameError
, kuris patikrina, ar išimtis buvo iškelta dėl pateikto vardo.
Vardas gali būti pateiktas kaip simbolis arba eilutė. Simbolis yra tikrinamas su grynuoju konstantos vardu, o eilutė - su visiškai kvalifikuotu konstantos vardu.
PATARIMAS: Simbolis gali reikšti visiškai kvalifikuotą konstantos vardą, pvz., :"ActiveRecord::Base"
, todėl simboliams apibrėžtas elgesys yra patogumo sumetimais, o ne dėl techninių priežasčių.
Pavyzdžiui, kai veiksmas ArticlesController
yra iškviestas, „Rails“ optimistiškai bando naudoti ArticlesHelper
. Tai nesvarbu, kad pagalbinės modulio nėra, todėl jei išimtis dėl tos konstantos vardo yra iškelta, ji turėtų būti nutildyta. Tačiau gali būti atvejis, kad articles_helper.rb
iškelia NameError
dėl faktiškai nežinomos konstantos. Tai turėtų būti pakartotinai iškelta. Metodas missing_name?
suteikia galimybę atskirti abu atvejus:
def default_helper_module!
module_name = name.delete_suffix("Controller")
module_path = module_name.underscore
helper module_path
rescue LoadError => e
raise e unless e.is_missing? "helpers/#{module_path}_helper"
rescue NameError => e
raise e unless e.missing_name? "#{module_name}Helper"
end
PASTABA: Apibrėžta active_support/core_ext/name_error.rb
faile.
20 Plėtiniai LoadError
Aktyvusis palaikymas prideda is_missing?
prie LoadError
.
Duodamas kelio pavadinimas, is_missing?
patikrina, ar išimtis buvo iškelta dėl to konkretaus failo (išskyrus galbūt ".rb" plėtinį).
Pavyzdžiui, kai veiksmas ArticlesController
yra iškviestas, „Rails“ bando įkelti articles_helper.rb
, bet to failo gali nebūti. Tai gerai, pagalbinis modulis nėra privalomas, todėl „Rails“ nutildyja įkėlimo klaidą. Tačiau gali būti atvejis, kad pagalbinis modulis egzistuoja ir savo ruožtu reikalauja kito trūkstamo bibliotekos. Tokiu atveju „Rails“ turi pakartotinai iškelti išimtį. Metodas is_missing?
suteikia galimybę atskirti abu atvejus:
def default_helper_module!
module_name = name.delete_suffix("Controller")
module_path = module_name.underscore
helper module_path
rescue LoadError => e
raise e unless e.is_missing? "helpers/#{module_path}_helper"
rescue NameError => e
raise e unless e.missing_name? "#{module_name}Helper"
end
PASTABA: Apibrėžta active_support/core_ext/load_error.rb
faile.
21 Plėtiniai Pathname
21.1 existence
existence
metodas grąžina gavėją, jei nurodytas failas egzistuoja, kitu atveju grąžina nil
. Tai naudinga idiomams, panašiems į šį:
content = Pathname.new("file").existence&.read
PASTABA: Apibrėžta active_support/core_ext/pathname/existence.rb
faile.
Atsiliepimai
Jūs esate skatinami padėti pagerinti šio vadovo kokybę.
Prašome prisidėti, jei pastebite rašybos klaidų ar faktinių klaidų. Norėdami pradėti, galite perskaityti mūsų dokumentacijos prisidėjimo skyrių.
Taip pat gali būti nepilnos informacijos arba informacijos, kuri nėra atnaujinta. Prašome pridėti bet kokią trūkstamą dokumentaciją pagrindiniam. Patikrinkite Edge vadovus pirmiausia, ar problemas jau išspręsta arba ne pagrindinėje šakoje. Patikrinkite Ruby on Rails vadovų gaires dėl stiliaus ir konvencijų.
Jei dėl kokios nors priežasties pastebite kažką, ką reikia ištaisyti, bet negalite patys tai pataisyti, prašome pranešti apie problemą.
Ir galiausiai, bet ne mažiau svarbu, bet koks diskusijos dėl Ruby on Rails dokumentacijos yra labai laukiamos oficialiame Ruby on Rails forume.