% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/findGlobals.R, R/globalsOf.R
\name{findGlobals}
\alias{findGlobals}
\alias{globalsOf}
\title{Get all global objects of an expression}
\usage{
findGlobals(
  expr,
  envir = parent.frame(),
  ...,
  attributes = TRUE,
  tweak = NULL,
  dotdotdot = c("warning", "error", "return", "ignore"),
  method = c("ordered", "conservative", "liberal", "dfs"),
  substitute = FALSE,
  unlist = TRUE,
  trace = FALSE
)

globalsOf(
  expr,
  envir = parent.frame(),
  ...,
  method = c("ordered", "conservative", "liberal", "dfs"),
  tweak = NULL,
  locals = NA,
  substitute = FALSE,
  mustExist = TRUE,
  unlist = TRUE,
  recursive = TRUE,
  skip = NULL
)
}
\arguments{
\item{expr}{An R expression.}

\item{envir}{The environment from where to search for globals.}

\item{attributes}{If TRUE (default), attributes of \code{expr} are also searched.
If FALSE, they are not.
If a character vector, then attributes with matching names are searched.
Note, the attributes of the attributes' elements are not searched, that is,
attributes are not searched recursively.  Also, attributes are searched
with \code{dotdotdot = "ignore"}.}

\item{tweak}{An optional function that takes an expression
and returns a tweaked expression.}

\item{dotdotdot}{TBD.}

\item{method}{A character string specifying what type of search algorithm
to use.}

\item{substitute}{If TRUE, the expression is \code{substitute()}:ed,
otherwise not.}

\item{unlist}{If TRUE, a list of unique objects is returned.
If FALSE, a list of \code{length(expr)} sublists.}

\item{trace}{TBD.}

\item{locals}{Should globals part of any "local" environment of
a function be included or not?}

\item{mustExist}{If TRUE, an error is thrown if the object of the
identified global cannot be located.  Otherwise, the global
is not returned.}

\item{recursive}{If TRUE, found globals are searched for additional globals.
For example, a closure (function) that exists outside a package
namespace may contain additional globals. Similarly, a formula
may depend on globals.}

\item{skip}{(internal) A list of globals not to be searched for
additional globals.  Ignored unless \code{recursive} is TRUE.}

\item{\ldots}{Not used.}
}
\value{
\code{findGlobals()} returns a character vector.

\code{globalsOf()} returns a \link{Globals} object.
}
\description{
Get all global objects of an expression
}
\details{
There are currently three strategies for identifying global objects.

The \code{method = "ordered"} search method identifies globals such that
a global variable preceding a local variable with the same name
is not dropped (unlike the \code{"conservative"} method).

The \code{method = "conservative"} search method tries to keep the number
of false positives to a minimum, i.e. the identified objects are
most likely true global objects.  At the same time, there is
a risk that some true globals are not identified (see example).
This search method returns the exact same result as the
\code{\link[codetools]{findGlobals}()} function of the
\pkg{codetools} package.

The \code{method = "liberal"} search method tries to keep the
true-positive ratio as high as possible, i.e. the true globals
are most likely among the identified ones.  At the same time,
there is a risk that some false positives are also identified.

The \code{method = "dfs"} search method identifies globals in
the abstract syntax tree (AST) using a depth-first search, which
better emulates how the R engine identifies global variables.

With \code{recursive = TRUE}, globals part of locally defined
functions will also be found, otherwise not.
}
\examples{
b <- 2
expr <- substitute({ a <- b; b <- 1 })

## Will _not_ identify 'b' (because it's also a local)
globalsC <- globalsOf(expr, method = "conservative")
print(globalsC)

## Will identify 'b'
globalsL <- globalsOf(expr, method = "liberal")
print(globalsL)
}
\seealso{
Internally, the \pkg{codetools} package is utilized for
code inspections.
}
