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。)