UseMethod("t")
сообщает вам, что t()
является общей функцией ( S3 ), которая имеет методы для разных классов объектов.
Для классов S3 вы можете использовать функцию methods
для перечисления методов для определенной общей функции или класса.
> methods(t)
[1] t.data.frame t.default t.ts*
Non-visible functions are asterisked
> methods(class="ts")
[1] aggregate.ts as.data.frame.ts cbind.ts* cycle.ts*
[5] diffinv.ts* diff.ts kernapply.ts* lines.ts
[9] monthplot.ts* na.omit.ts* Ops.ts* plot.ts
[13] print.ts time.ts* [<-.ts* [.ts*
[17] t.ts* window<-.ts* window.ts*
Non-visible functions are asterisked
«Невидимые функции являются звездочками» означает, что функция не экспортируется из пространства имен пакета. Вы можете просмотреть исходный код с помощью функции :::
(т. Е. stats:::t.ts
) или с помощью getAnywhere()
. getAnywhere()
полезен, потому что вам не нужно знать, из какого пакета появилась функция.
> getAnywhere(t.ts)
A single object matching ‘t.ts’ was found
It was found in the following places
registered S3 method for t from namespace stats
namespace:stats
with value
function (x)
{
cl <- oldClass(x)
other <- !(cl %in% c("ts", "mts"))
class(x) <- if (any(other))
cl[other]
attr(x, "tsp") <- NULL
t(x)
}
Система S4 - это более новый метод отправки и является альтернативой системе S3. Вот пример функции S4:
> library(Matrix)
Loading required package: lattice
> chol2inv
standardGeneric for "chol2inv" defined from package "base"
function (x, ...)
standardGeneric("chol2inv")
Methods may be defined for arguments: x
Use showMethods("chol2inv") for currently available ones.
Вывод уже содержит много информации. standardGeneric
является индикатором функции S4. Предлагается метод для просмотра определенных методов S4:
> showMethods(chol2inv)
Function: chol2inv (package base)
x="ANY"
x="CHMfactor"
x="denseMatrix"
x="diagonalMatrix"
x="dtrMatrix"
x="sparseMatrix"
getMethod
может использоваться для просмотра исходного кода одного из методов:
> getMethod("chol2inv", "diagonalMatrix")
Method Definition:
function (x, ...)
{
chk.s(...)
tcrossprod(solve(x))
}
Signatures:
x
target "diagonalMatrix"
defined "diagonalMatrix"
также методы с более сложными сигнатурами для каждого метода, например
require(raster)
showMethods(extract)
Function: extract (package raster)
x="Raster", y="data.frame"
x="Raster", y="Extent"
x="Raster", y="matrix"
x="Raster", y="SpatialLines"
x="Raster", y="SpatialPoints"
x="Raster", y="SpatialPolygons"
x="Raster", y="vector"
Чтобы увидеть исходный код для одного из этих методов, должна быть поставлена целая сигнатура, например
getMethod("extract" , signature = c( x = "Raster" , y = "SpatialPolygons") )
Недостаточно предоставить частичную подпись
getMethod("extract",signature="SpatialPolygons")
#Error in getMethod("extract", signature = "SpatialPolygons") :
# No method found for function "extract" and signature SpatialPolygons
В случае ts.union
, .cbindts
и .makeNamesTs
являются невыполненными функциями из пространство имен stats
. Вы можете просмотреть исходный код невыгруженных функций с помощью оператора :::
или getAnywhere
.
> stats:::.makeNamesTs
function (...)
{
l <- as.list(substitute(list(...)))[-1L]
nm <- names(l)
fixup <- if (is.null(nm))
seq_along(l)
else nm == ""
dep <- sapply(l[fixup], function(x) deparse(x)[1L])
if (is.null(nm))
return(dep)
if (any(fixup))
nm[fixup] <- dep
nm
}
Обратите внимание, что «скомпилированный» не обратитесь к байт-компилированному R-коду, созданному пакетом компилятора. Строка
в приведенном выше выводе указывает, что функция скомпилирована в байтах, и вы все еще можете просмотреть источник из командной строки R.
Функции, вызывающие .C
, .Call
, .Fortran
, .External
, .Internal
или .Primitive
вызывают точки входа в скомпилированном коде, поэтому вам нужно будет искать источники скомпилированного кода, если вы хотите полностью понять эту функцию. Это зеркало GitHub исходного кода R - достойное место для запуска. Функция pryr::show_c_source
может быть полезным инструментом, так как она приведет вас непосредственно на страницу GitHub для вызовов .Internal
и .Primitive
. Пакеты могут использовать .C
, .Call
, .Fortran
и .External
; но не .Internal
или .Primitive
, поскольку они используются для вызова функций, встроенных в интерпретатор R.
Вызовы некоторых из вышеперечисленных функций могут использовать объект вместо символьной строки для ссылки на скомпилированные функция. В этих случаях объект имеет класс "NativeSymbolInfo"
, "RegisteredNativeSymbol"
или "NativeSymbol"
; и печать объекта дает полезную информацию. Например, optim
вызывает .External2(C_optimhess, res$par, fn1, gr1, con)
(обратите внимание, что это C_optimhess
, а не "C_optimhess"
). optim
находится в пакете статистики, поэтому вы можете ввести stats:::C_optimhess
, чтобы просмотреть информацию о вызываемой скомпилированной функции.
Если вы хотите просмотреть скомпилированный код в пакете, вам нужно будет загрузить / распаковать исходный код пакета. Установленных двоичных файлов недостаточно. Исходный код пакета доступен из одного и того же CRAN (или совместимого с CRAN) репозитория, из которого первоначально был установлен пакет. Функция download.packages()
может получить источник пакета для вас.
download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")
Это загрузит исходную версию пакета Matrix и сохранит соответствующий файл .tar.gz
в текущем каталоге. Исходный код для скомпилированных функций можно найти в каталоге src
несжатого и нераспределенного файла. Разомкнутый и необратимый шаг можно выполнить за пределами R
или из R
с помощью функции untar()
. Можно объединить шаг загрузки и расширения в один вызов (обратите внимание, что один и тот же пакет может быть загружен и распакован таким образом):
untar(download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")[,2])
В качестве альтернативы, если разработка пакета (например, через GitHub , R-Forge или RForge.net ), вы можете, вероятно, просмотреть исходный код онлайн.
Некоторые пакеты считаются «базовыми» пакетами. Эти пакеты поставляются с R, и их версия блокируется версией R. Примеры включают base
, compiler
, stats
и utils
. Таким образом, они недоступны в виде отдельных загружаемых пакетов на CRAN, как описано выше. Скорее, они являются частью дерева источников R в отдельных каталогах пакетов в /src/library/
. Как получить доступ к источнику R, описан в следующем разделе.
Если вы хотите просмотреть встроенный код в интерпретаторе R, вы необходимо будет загрузить / распаковать источники R; или вы можете просмотреть источники в Интернете через репозиторий R Subversion или github mirror Winston Chang
.
Новая статья R Uwe Ligges [PDF] (стр. 43) является хорошей общей ссылкой о том, как просматривать исходный код для функций .Internal
и .Primitive
. Основные шаги - сначала искать имя функции в src/main/names.c
, а затем искать имя «C-entry» в файлах в src/main/*
.
ECMAScript не предоставляет доступа к внутренним слотам [[ProxyHandler]] и [[ProxyTarget]].
Некоторые реализации могут предоставлять некоторые нестандартные способы, но не воспринимают это как должное.
Например, в привилегированном коде Firefox вы можете узнать, является ли объект прокси-сервером с помощью
Components.utils.isProxy(object);
Я предложил реализовать аналогичные методы, чтобы показать [[ProxyHandler]] и [ [ProxyTarget]]. Они сказали мне реализовать их в Debugger.Object
вместо Components.utils
.
Когда патч земли, можно будет использовать что-то вроде
Components.utils.import('resource://gre/modules/jsdebugger.jsm');
var Cc = Components.classes;
// Add a debugger to a new global
var global = new Components.utils.Sandbox(
Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal),
{ freshZone: true }
);
addDebuggerToGlobal(global);
var dbg = new global.Debugger().addDebuggee(this);
// Create a debugger object of your object, and run proxy getters
var dbgObj = dbg.makeDebuggeeValue(object);
if(dbgObj.isProxy) { // a boolean
dbgObj.proxyHandler.unsafeDereference(); // the [[ProxyHandler]]
dbgObj.proxyTarget.unsafeDereference(); // the [[ProxyTarget]]
}
Добавить свойство «специального» собственного дескриптора в getOwnPropertyDescriptor
const target = {
//Fns ..
//Props ...
};
const handler = {
getOwnPropertyDescriptor(target, prop) {
if(prop == "[[handler]]"){
return { configurable: true, enumerable: true, value: this };
}
return undefined;
},
prop1: 'abcd'
};
const proxy = new Proxy(target, handler);
console.log(Object.getOwnPropertyDescriptor(proxy, '[[handler]]').value.prop1);