Expand description
$ / [[ field methods of r_data_accessors for S3, S4 and env classes (#1848).
$ / [[ field syntax for the #[r_data] fields of S3, S4 and env
classes: s3(r_data_accessors), s4(r_data_accessors),
env(r_data_accessors), and their getters-only form
r_data_accessors = "get" (#1848).
The methods call the helpers #[derive(ExternalPtr)] emits for the type
(.rdata_fields_T, .rdata_get_T, .rdata_set_T, .rdata_no_field_T,
see externalptr_derive::generate_field_syntax_helpers), which call the
per-field .Call() accessors. Those carry no call slot (#344, #348), so
each method raises a tagged condition value with its own frame as the
fallback (environment()), which .miniextendr_frame_call turns into the
generic’s call: x$keys, x$keys <- value (#1851).
No reader matches a prefix of a name (#1922). On an S3 bare pointer $
and [[ take an exact field name, and [[ also a whole-number position
in the field order (subscriptOutOfBoundsError past the last field,
through the preamble’s .miniextendr_field_at); an unknown name raises
miniextendr_no_field there, as a write does (#1921).
s3(r_data_accessors, lookup = "list") keeps a list’s other lenience
(#1891): an unknown name or NA reads NULL, and [[ takes a logical
or a fractional position (truncated) as a list’s does. In both, a [[
index that is neither one name nor one position raises the preamble’s
.miniextendr_field_index_error (the type’s field_error classes, then
notSubsettableError, on the user’s call) instead of reaching
[[.default (#1920). The S3 class also gets names() (the field names),
as.list() (every field, in order, NULL fields kept; #1890) and
.DollarNames() (#1885), and S4 and env classes .DollarNames(). A name
that is not a field falls through on a list or an environment receiver,
by the exact name: $ reads a list’s element with .subset2() (R’s $
on a list matches a prefix) and an environment’s through NextMethod(),
[[ and the writes go to R’s own [[ (with exact = TRUE) / $<- /
[[<-, as do names() and as.list() there (as.list.environment()
by name on an environment, whose class attribute would send
NextMethod() to the default method, which can’t coerce one). The writes
raise miniextendr_no_field, naming the R class and its fields, on a bare
pointer (an S3 or env object), as $ does on an S4 object, which have
nothing to fall through to. A [[<- index that is not a name falls
through. Under restored(refuse = "every_read") every S3 reader first
checks a pointer, list or environment receiver (#1901, #1919): a restored
pointer and a list or environment without one are refused before the
index is looked at. Every replacement method puts value last and
returns the object (#1853).
The S3 [[, as.list() and [[<- take ... because their generics
do, and read none of it on a bare pointer, so there they refuse every
argument in it (#2174) with dots = empty’s check (dots_policy), on
the generic’s call, with the formal each one most likely meant and the
type’s field_error classes in front: x[["data", exatc = TRUE]],
x[[1, 2]], as.list(x, all.names = TRUE), x[["data", 2]] <- v. [[
takes exact as a formal after ..., as [[.data.frame does, so
exact = FALSE is no extra argument; field names match exactly whatever
it says. A list or environment receiver hands its dots on, as before. An
env class’s [[ (env_class.rs) takes exact the same way and refuses
the rest on every receiver, since nothing reads its dots.
A field fallback (fallback = "Self::f", #2150; see
miniextendr_impl::FieldFallback) answers the names no field has
on the bare pointer, through a .Call entry the impl block emits
(fallback_c_entries): $ and [[ by name on an S3 object, $ on an
S4 object, and $ / [[ on an env object after its methods. The
fallback’s None reads what an unknown name reads without it. Fields win,
a position counts the fields only, names(), as.list() and the writes
don’t see it, and a list or environment receiver keeps its own elements
for those names. With fallback_names = "Self::g", .DollarNames()
offers the fallback’s names after the fields (and an env class’s
methods).
.DollarNames() is registered with @exportS3Method utils::.DollarNames
(S3method(utils::.DollarNames, Class)): the @method + @export pair
writes an unqualified S3method(.DollarNames, Class), which fails to load
with only base attached (R CMD check loads a namespace that way). S4
takes the same S3 method, which utils dispatches on the S4 class.
Structs§
- Helpers 🔒
- The names of the type’s field helpers.
Constants§
- AS_
LIST_ 🔒FORMALS - The formals of the S3
as.list()reader, its generic’s. - ENV_
SUBSET_ 🔒FORMALS - The formals of an env class’s
[[: its$’s, then...andexact, as the S3[[has them (#2174). - SUBSET_
ASSIGN_ 🔒FORMALS - The formals of the S3
[[<-writer,valuelast (#1853). - SUBSET_
FORMALS 🔒 - The formals of the S3
[[reader:exactafter..., as[[.data.framehas it, so R matches it by name and...holds only what the reader refuses (#2174).
Functions§
- check_
collisions 🔒 - Refuses an impl method on a generic the field methods define: two
definitions of
$.Class(orsetMethod("$", "Class")) would follow, and the later one would win. The getters-only form generates no$<-/[[<-, so a hand-written one is the point of it; the readers ($,[[,names,as.listand.DollarNameson S3,$and.DollarNameson S4) are generated in both forms. Env classes have no check: their methods are not S3 methods. - dollar_
names_ 🔒doc - The roxygen block of a
.DollarNames.<Class>method: on the class’s topic (page_lines) for an exported class with a page, else no page, and registered with@exportS3Method utils::.DollarNameswhenregisteris set (see the module docs for why not@method+@export). - dots_
check 🔒 - The check a method with
formalsmakes before it reads its index (#2174):dots = empty’s statement (DotsPolicy::r_check), which refuses every argument in...on the generic’s call (the method’s frame), with the formal each one most likely meant.classis an R expression for the classes in front, the type’sfield_errorclasses. - env_
dollar_ 🔒names .DollarNames.Classfor an env class withenv(r_data_accessors): the fields, then the class’s methods (ls(<Class>)), since$reaches both.on_pagefollows the$.Classblock’s gating; the method is always registered, as$.Classis.- env_
field_ 🔒branch - The field branch at the top of an env class’s
$.Class(and its[[.Classalias), ahead of the method lookup: a field wins over a method of the same name, as R6’s active bindings do, and a field read doesn’t pay for the lookup. - env_
load_ 🔒check - The load check of an env class with
env(r_data_accessors). - env_
name_ 🔒param - The
@param nametext of an env class’s$.Class. - env_
replacement_ 🔒methods $<-.Classand its[[<-.Classalias for an env class withenv(r_data_accessors). An env object is a classed pointer, so a name that is not a field raisesminiextendr_no_field; a list or environment carrying the pointer in.ptrwrites its own element (NextMethod()).on_pagefollows the$.Classblock’s gating; the methods are always registered, as$.Classis.- env_
subset_ 🔒dots_ check - The first line of an env class’s
[[(#2174): it takes no argument pastnamebutexact, which it ignores (field and method names match exactly), and nothing reads its..., on any receiver. Underenv(r_data_accessors)the refusal carries the type’sfield_errorclasses. - env_
unknown_ 🔒name_ check - The check in an env class’s
$.Classbefore it returnsNULLfor a name that is neither a field nor a method: underrestored(refuse = "every_read")a pointer without its Rust value raises the type’s restored error there (#1901). With afallback(#2150) the bare pointer then asks it, after the fields and the methods, so a value of the fallback never hides a method; itsNonereadsNULL, as an unknown name does. - fallback_
c_ 🔒entries - The
.Callentries of the impl’s field fallback (#2150):fallback = "Self::f"asC_<crate>__mx_rdata_fallback_<Type>(x, name, none), andfallback_names = "Self::g"asC_<crate>__mx_rdata_names_<Type>(x). Nothing without a fallback. - guard 🔒
- The tagged-condition guard after an accessor call: the method’s frame is the raise fallback, resolved to the generic’s call (#1851).
- load_
check 🔒 - A top-level check, emitted next to the class’s methods, that the type has
the field helpers: an impl that opts in for a type without an
RSidecarselector or without apub#[r_data]field fails at install time instead of at the first$(for env, at every method call). - not_
a_ 🔒field_ name - The test of a
[[/[[<-index (or env’s$/[[name): a field name is a length-1 character vector naming a field. - page_
lines 🔒 - The page lines of a field method’s block:
@rdnameits topic (topic) with the@paramlines ofparamsthe page needs, or, on a topic the author names with the impl’s@rdname,@order NaNand no@paramlines: the topic’s own block documents the arguments, and a later block’s@paramwould replace its text (#1590). - param_
lines 🔒 - The
@paramlines of the field methods on the class page, without the names the constructor documents there: roxygen2 keeps the last@paramof a name on a page, and these blocks must not replace the constructor’s text. An env class’sClass$new()lists its arguments in a\describe{}list, not as@paramlines, so it takes nothing away. (The type’s standalone accessors, which documentedx/valueon the page named after the type, are internal under field syntax, #1900.) - s3_
field_ 🔒methods $.Class,[[.Class,names.Class,as.list.Classand.DollarNames.Class, and with setters$<-.Class/[[<-.Class, for an S3 class withs3(r_data_accessors).- s3_
method_ 🔒doc - The roxygen block of an S3 or env field method
<generic>.<Class>: on the class’s topic (page_lines) for an exported class with a page, else no page. The method is registered (S3method()) whenregisteris set. - s4_
field_ 🔒methods setMethod("$"),.DollarNames.Class, and with setterssetMethod("$<-"), for an S4 class withs4(r_data_accessors). An S4 object of the class is no list (its only slot isptr), so a name that is not a field raisesminiextendr_no_field. The methods passx@ptrto the accessors..DollarNamesis an S3 method, whichutilsdispatches on the S4 class; it is registered unless the class isnoexport, as an S3 class’s methods are.- topic 🔒
- The help topic of the field methods (and of the S3 class environment):
the impl block’s own
@rdname, else the class page (#1900).