Ramda:如何在没有 `R.wrap` 的情况下修改函数参数?
Ramda: How to modify function parameters without `R.wrap`?
如何在不换行的情况下覆盖方法参数默认值(因为它即将被删除)。考虑以下因素。
let foo = (bar, { logToConsole = false }) => {
if (logToConsole) console.log(bar);
return bar;
};
// I want foo to always log, but I want to leave the option open to
// override that on a per instance basis (which excludes doing a
// `R.partial`). Looking at the methods available, `wrap` seems to
// do what I want...
foo = R.wrap(foo, (fn, bar, options) => {
options = R.merge({ logToConsole: true }, options);
return fn(bar, options);
}
所以,重新分配 foo,默认翻转。每次我调用 foo
之后,它都会更改默认值。
由于 wrap
已弃用,我应该改用什么?
我遵循了 this thread,但没有看到如何通过示例解决此模式。
感谢您的帮助!
我建议采用不同的方法。我假设选项散列始终是最后一个参数。如果是这种情况,可以写一个装饰器:
function logLastArg(f) {
return R.curryN(f.length, function() {
console.log(R.last(arguments));
return R.apply(f, arguments);
});
}
function query(queryString, dbOpts) {
return ['foo', 'bar', 'baz'];
}
var queryWithLogging = logLastArg(query);
query('SELECT username FROM users', {name: 'default'});
// => ['foo', 'bar', 'baz']
queryWithLogging('SELECT username FROM users', {name: 'default'});
// logs "{name: 'default'}"
// => ['foo', 'bar', 'baz']
那个讨论涉及 David,他展示了我为 wrap 提出的每一个用法都可以更简单地重写,尤其是在 ES6 方便的情况下。
我不确定他是否正确,但相差不远。多年来我一直在使用 wrap
之类的东西,在 JS 中做 AOP 风格的工作,现在我仍然这样做,只是没有在 Ramda 中使用它。它们是否都可以用不同的方式重写,一致地写它们对我很有用,但大卫的观点很好。
我相信您的案例可以非常直接地重写:
const foo2 = (bar, options) => foo(bar, R.merge({logToConsole: true}, options));
foo2(42);
// logs 42
//=> 42
foo2(99, {logToConsole: false});
// (doesn't log)
//=> 99
(我假设原文中的 command
应该是 bar
。对吗?)
更新
如果您希望重新分配 foo
,您可以像这样结束它:
foo = ((orig) =>
(bar, options) => orig(bar, R.merge({logToConsole: true}, options))
)(foo);
这与上面的 foo2
具有相同的行为。 (显然它不适用于 const
声明的 foo
。)
如何在不换行的情况下覆盖方法参数默认值(因为它即将被删除)。考虑以下因素。
let foo = (bar, { logToConsole = false }) => {
if (logToConsole) console.log(bar);
return bar;
};
// I want foo to always log, but I want to leave the option open to
// override that on a per instance basis (which excludes doing a
// `R.partial`). Looking at the methods available, `wrap` seems to
// do what I want...
foo = R.wrap(foo, (fn, bar, options) => {
options = R.merge({ logToConsole: true }, options);
return fn(bar, options);
}
所以,重新分配 foo,默认翻转。每次我调用 foo
之后,它都会更改默认值。
由于 wrap
已弃用,我应该改用什么?
我遵循了 this thread,但没有看到如何通过示例解决此模式。
感谢您的帮助!
我建议采用不同的方法。我假设选项散列始终是最后一个参数。如果是这种情况,可以写一个装饰器:
function logLastArg(f) {
return R.curryN(f.length, function() {
console.log(R.last(arguments));
return R.apply(f, arguments);
});
}
function query(queryString, dbOpts) {
return ['foo', 'bar', 'baz'];
}
var queryWithLogging = logLastArg(query);
query('SELECT username FROM users', {name: 'default'});
// => ['foo', 'bar', 'baz']
queryWithLogging('SELECT username FROM users', {name: 'default'});
// logs "{name: 'default'}"
// => ['foo', 'bar', 'baz']
那个讨论涉及 David,他展示了我为 wrap 提出的每一个用法都可以更简单地重写,尤其是在 ES6 方便的情况下。
我不确定他是否正确,但相差不远。多年来我一直在使用 wrap
之类的东西,在 JS 中做 AOP 风格的工作,现在我仍然这样做,只是没有在 Ramda 中使用它。它们是否都可以用不同的方式重写,一致地写它们对我很有用,但大卫的观点很好。
我相信您的案例可以非常直接地重写:
const foo2 = (bar, options) => foo(bar, R.merge({logToConsole: true}, options));
foo2(42);
// logs 42
//=> 42
foo2(99, {logToConsole: false});
// (doesn't log)
//=> 99
(我假设原文中的 command
应该是 bar
。对吗?)
更新
如果您希望重新分配 foo
,您可以像这样结束它:
foo = ((orig) =>
(bar, options) => orig(bar, R.merge({logToConsole: true}, options))
)(foo);
这与上面的 foo2
具有相同的行为。 (显然它不适用于 const
声明的 foo
。)