Recently I came across a method, which looks like: add(1).(2).
It was on Code Wars. I just should take this 2 argumenst and make them equated 3. It's easy part, I think, but I have never seen any arguments like this(I am newbie).
Do you have a source where I could read about it? Or could you explain it?
If you need more information, I take this example from here: https://www.codewars.com/kata/539a0e4d85e3425cb0000a88/train/ruby
This is a shorthand notation to call a proc or lambda expression
proc.call(arg)
proc[arg]
proc.(arg)
proc::(arg)
Are all equivalent.
Actually this works with any object that responds to call since Ruby is duck-typed like that.
Related
I have some old code that looks like:
some_variable = "-> (params) { Company.search_by_params(params) }"
if eval(some_variable).is_a?(Proc)
...
Rubocop is complaining about the use of eval. Any ideas on how to remove the usage of eval?
I don't really understand Procs so any guidance on that would be appreciated.
Simple. Don't define your variable object as a string but as a lambda Proc
my_lamda = -> (params) { Company.search_by_params(params) }
if my_lambda.is_a?(Proc)
#do stuff
end
But why would you instantiate a string object which contains what appears to be a normal lambda which is a Proc, when you can define a Proc instead?
I am going to answer the question "If I want to run code at a later time, What is the difference between using a proc and a eval'd string?" (which I think is part of your question and confusion):
What eval does is take a string and parses it to code, and then runs it. This string can come from anywhere, including user input. But eval is very unsafe and problematic, especially when used with raw user input.
The problems with eval are usually:
There is almost always a better way to do it
Very dangerous and insecure
Makes debugging difficult
Slow
Using eval allows full control of the ruby process, and if you have high permissions given to the ruby process, potentially even root acmes to the machine. So the general recommendation is use 'eval' only if you absolutely have no other options, and especially not with user input.
Procs/lambdas/blocks also let you save code for later, (and solve most of the problems with eval, they are the "better way") but instead of storing arbitrary code as a string to read later, they are code already, already parsed and ready to go. In someways, they are methods you can pass around later. Making a proc/lambda gives you an object with a #call method. Then when you later want to run the proc/block/lambda, you call call([arguments...]). What you can't do with procs though is let users write arbitrary code (and generally that's good). You have to write the code for the proc in a file ruby loads (most of the time). Eval does get around that, but you really should rethink if you really want that to be possible.
Your code sample oddly combines both these methods: it evaluates a string to a lambda. So what's happening here is eval is running the code in the string right away and returning the (last) result, which in this case happens to be a lambda/proc. (Note that this would happen every time you ran eval, which would result in multiple copies of the proc, with different identities, but the same behavior). Since the code inside the string happens to make a lambda, the value returned is a Proc which can later be #call'd. So when eval is run, the code is parsed, and a new lambda is created, with the code in the lambda stored to be run at a later time. If the code inside the string did not create a lambda, the all that code would be run immediately when eval was called with the string.
This behavior might be desired, but there is probably a better way to do this, and this is definitely a foot-gun: there are at least a half dozen subtle ways this code could do unintended things if you weren't really careful with it.
Look at the following line of chef code:
node.default['apache']['dir'] = '/etc/apache2'
In the official chef docs, it says 'node' is an object, and 'default' is a method of it, so how can square brackets(I thought this is hash syntax) follow a method?
I come from Python background and I'm new to Ruby, maybe this is general syntax, or maybe this is Chef-specific syntax, I'm just confused about this syntax.
node.default() (which is really an alias for node.attributes().default()) returns an instance of a Chef::Node::VividMash which works kind of like a normal Hash object but implements the deep-set behavior you see there (where you can set a deeply nested key without creating the intervening levels).
tl;dr don't worry about, we do a lot of object trickery to make the DSL look as nice as possible.
While debugging abap code I found an interessting code construct.
method_name(: Parameter1 ), Parameter2 ).
As far as I can tell this one calls the method twice. The first time with the first parameter and the second time with the second.
Unfortunately I have no idea how this construct is called and so I can't find any documentation in the SAP docu or with google.
I can tell that this works but is this an official construct?
Does it work with more than two parameters? (E.g. four times)
Best regards,
Dirk
Congratulations, you've found an obscure and most certainly discouraged use of a so-called chained statement. Using this for method calls is not recommended, but since it was once allowed, SAP will be very reluctant to remove this again...
When the ABAP compiler finds a colon, it first expands it blindly without any syntax check (expanding A:B,C,D. into A B. A C. A D.).
And only then it analyses the syntax of each of them - to tell whether it is an assignment, method call or whatever. Pavel
Similar to __callee__, is there something which returns the calling method? I realize there is the caller which I amble to strip the name of the caller method from but I am curious is there is a standard method for returning the name of the calling method without any other information along with it.
There is no such feature in MRI. But there are some alternatives.
In case you happen to use Rubinius, you can do this instead of parsing caller:
Rubinius::VM.backtrace(1, false).first.name
#=> :calling_method_name
You can also use a gem to parse the result of caller for you. It should work for any Ruby > 1.9.
The answer to this SO question describes how you can do some simple parsing yourself.
And finally, there appears to be work in progress on getting a feature like this into Ruby 2.0, although the relevant ticket has not been updated for a while.
Is there any possibility to establish in method_missing declaration in Ruby whether a given missing_method was called (without any arguments) using parentheses notation, ie:
foo.non_existing_method()
or using parentheses-less notation:
foo.non_existing_method
?
I need this to solve my very specific testing problem.
No.
Since both are exactly the same, there cannot possibly be a way to detect the difference.
It doesn't make sense anyway, since both are exactly the same, so there cannot possibly any behavorial difference, either.
If you could detect the difference, then you could also have your method behave differently, which would be extremely surprising to any user of that method.