Open dannybeckett opened 11 years ago
How do you pass arguments to it? (ok since you edited), they could be passed the same way as learn probably, with a regex
May I +1? Please? Ple-e-e-ase?
@ci11
!!learnEval command "js_source"
Ok, maybe like this then:
!!learnEval myEcho "function(msg) { return msg; }"
!!learnEvalC reverse "(msg) -> esrever.reverse msg"
!!learnEval reverse "(x)=> x.split('').reverse().join('')" \w+ !!reverse racecar
racecar
No need to use regexps, however might be quite useful sometimes. And what should we do with large codeblocks? Maybe just indent them?
!!learnEvalC reverse
(str) =>
doABarrelRoll ()
youtube.getVideo("oHg5SJYRHA0")
str.split('').reverse().join('')
Offtop: x.split('').reverse().join('')
is bad.
I said this once. I still think it'd be pretty cool.
On Oct 19, 2013, at 12:48 PM, dannybeckett notifications@github.com wrote:
It would be cool if there was a learnEval command, to execute learned JS commands.
E.g.
!!learnEval dannydivisor "var number = 31861, divisors = []; for(var i = 1; i <= number; i++) if(number % i === 0) divisors.push(i); divisors;" Would output:
[1,151,211,31861] — Reply to this email directly or view it on GitHub.
Yes, I like the idea and I think that we'll do it just the way @ci11 proposed since it is the same way we handle this in the learn
command.
What about just accepting a function and using its arguments?
How would this incorporate response patterns? <> | <msg> | <user>
If an argument is named user
or msg
then the appropriate value is passed.
!!learnEval function sum(a,b){ return a+b;}
Or without the function keyword
!!learnEval sum(a,b){ return a+b;}
Execution:
!!sum 5 10
> 15
Something like func.apply({}, input.match(/\w+/g))
?
@benjamingr I don't like that at all to be honest.
function a() {}: function b() {}; ...
?I think having like as close to the command definition as possible would be the best way.
!!learnEval "name" "<>" "actual code" "argument pattern"
I split up the message type pattern on purpose, maybe it is worth thinking about splitting them out even in the normal command definitions.
@mainerror seriously? You'd rather have regex patterns and strange arguments over a straight up JS function?
A function is the basic JavaScript construct containing code that's aimed at executing a command. The language has blessed us with such a simple construct. Why not use it?
I would say that all arguments (
On Oct 21, 2013, at 12:41 PM, Shmiddty notifications@github.com wrote:
How would this incorporate response patterns? <> |
| — Reply to this email directly or view it on GitHub.
To make this safe, we would need to extend the eval functionality that is already there, and provide an object to the running code, to access some of the bot's API functionality.
Accepting a function sounds silly, why not just do what commands already do (which is pretty much what shell does): Accept $0
, $1
and so forth?
/learnEval foobar 'You know, $0 smells a lot like foo bar' 'Tells you the truth about things which smell like foobar'
/foobar yo mama
And pass the result of parsing it according to the bot's innate argument parsing (the spaces/quotes things).
Since it's pure code, you can run a regexp if you want, or do any other wacky transformations. This way, we can also check if certain input patterns arise (a certain convention to accepting arguments), and consider adopting it into core.
As for output, it'd be a bit tricky. bot.eval
isn't too flexible, since it opts as both the command and the code runner. So we'd need to separate one of these parts out, and have the "purer" part (which just runs code) accept both code, and some information object which'll be passed along into the sandbox. On that, we can define a function or a flag or whatever which triggers how output is handled - as a "pure" message, or as a user/message reply.
@Zirak let's take fuckable as an example. If you have to pass the code to the command every time you call it, it defeats the purpose.
/learnEval fuckable 'You can safely fuck anyone older than $0' ...
/fuckable 28/2+7
Not much gained there.
What are we event talking about here? It seems to me that we're deriving from topic. This is not meant to be yet another console like print command but a way to have an evaluation saved.
@Shmiddty Of course the user doesn't have to supply the code...the user input is never part of the code, it's data passed to the code, just a variable.
/learnEval fuckable "You can shag down to $0/2+7"
Or, more realistically:
"You can shag down to Number($0)/2+7"
Why the need for a whole new command? Why not just improve and extend the learn command we have now?
One concern is, how to know when we're dealing with JS? We could use parenthesis:
/learn fuckable "No younger than (Number($0)/2+7)"
Result:
No younger than ##
So, how would (should?) it handle a case with variables?
/learn fuckable "(var safeAge = Number($0)/2+7)No younger than (safeAge)"
The problem now would be, the result being:
##Not younger than ##
But is all of that really better than this?
/learn fuckable {var safeAge = Number($0)/2+7; return "No younger than"+safeAge;}
Another variation, to save a little space, can be:
/learn fuckable {safeAge = Number($0)/2+7} "No younger than $safeAge"
Here, the optional setup block, fully capable of JS, provides some a extended parse variables to be included in the resulting block.
Imo, we just need to provide an enclosure, and since we're letting the parser take care of the arguments, there's no need for "function()". Using brackets instead of quotes can tell the parser when we're dealing with an extensive JS command, rather than a simple print command.
Or we could get the best or both worlds. When parsing a simple print command inside quotes, we could still recognize code between parenthesis, and when parsing and extensive command between brackets, the whole thing can be interpreted as one big block of code between parenthesis.
we could also have a global object for that, and access it from the current eval, it's probably more handy to define them in a js environment directly
!!> $.fuckable = (age) => age < 29;
!!> $.fuckable(27)
and have !!fuckable \w+ automatically activated then, (the learned commands would prevail over the $. methods) !!fuckable 28.9
@ci11 That creates a bit of weird dynamics and extra magic.
@shea-sollars That doesn't simplify things, it complicates them. It means all learned commands are now null and void, that /learn
now has to use elaborate parsing and composing techniques, and completely changes /learn
's dynamics. I'd rather have a relatively simpler /learn
which does much more basic copy-replace-paste operations and a more complex /learnEval
which handles input logic than have an omnitool /learn
which tries to do everything.
@Zirak If I understand correctly, you mean because of how learned commands are saved, but how would this be a problem if the setup/eval block should be optional, and would always come before any other arugments? I thought it would be pretty simple to distinguish an eval argument from a print argument, based on whether or not they are wrapped in quotes versus if they are wrapped in brackets. Maybe I am misunderstanding, because there is some specific syntax that this would break?
I did a little testing, and it is very easy to get the names/values of variables set in the global scope of a worker. Probably even easier than what I came up with, if we incorporate it into the foundation of the eval worker script. The main problem I see, is that it would either need to parse the arguments twice or, more preferably, in order. Which actually shouldn't be a problem, with the eval block always coming first. In fact, maybe the eval block shouldn't even be seen or recognized as an argument at all, by commands? The eval block could be restricted to the command parse, and pass a temporary object to it for the rest of the arguments, which allows it to recognize the extra values to parse. In return, this would become a new thing for all commands, and all of the work would just need to be done in parseCommandArgs.js.
/afk {var reasons=['eating','watching tv','masturbating']; reason=reasons[Math.round(Math.random()*(reasons.length-1))]} $reason
My concern with making it work in learned commands, is that it would need to parse the eval and print block each time the command is invoked.
Is that feature still doable in mid-term? macros like $rand
would be done in pure js, however there are still some security concern, for avoiding infinite recursion/loop that would more or less crash the bot I guess
It would be cool if there was a
learnEval
command, to execute learned JS commands.E.g.
When run with
!!divisor
, would output:It'd be even better if it could take arguments, e.g.
number
, so one could run!!divisor 456
.