How Does This Ruby Injection Magic Work

How does this ruby injection magic work?

There's no magic, symbol (method) is just one of the possible parameters. This is from the docs:

  # enum.inject(initial, sym) => obj
# enum.inject(sym) => obj
# enum.inject(initial) {| memo, obj | block } => obj
# enum.inject {| memo, obj | block } => obj

Ours case is the second one.

You can also rewrite it with traditional block:

op = :+   #  parameter of inject call
[1,2,3,4,5,6,7].inject {|sum, x| sum.send(op, x)} # also returns 28

(to answer "how does it work" part)

How does array.inject(:+) work?

When the sole argument to inject is not a symbol, it is used as the initial value, otherwise, to_proc and & are applied to the argument, and that is used as a block. When there are two arguments, the first one is used as the initial value, and the second one must be a symbol, and would be used to create a block as described above.

A drawback of this is that you cannot use a symbol as the initial value of inject, but it is probably considered that there is no use case for that. I don't think this specification is clean.

Why does my Fibonacci series using Ruby's inject doesn't work?

arr.last-1 doesnt work, try arr[-2] instead:

p (1..5).inject([1]) { |arr, x| x > 1 ? arr << arr.last + arr[-2] : arr << 1 }
#=>[1, 1, 2, 3, 5, 8]

-edit-
btw you don't need that ;arr at the end, << returns the array by default

Technique to inject dependencies in Ruby without using DI frameworks

Looks fine to me. Classes are objects in Ruby, so dependency injection is just setting a variable at runtime. In your case, you are setting the @http_client instance variable of the AppClient class. Once that variable is accessed by the code that needs the implementation, the class you configured the application with will be returned and it will do the job as long as it responds to the correct messages.

Be careful, though. Remember that classes are singleton objects that are shared within a single Ruby process. Other code could call that accessor method and change that variable as well. This could happen at any point, not just at start up, and will affect all code that uses the implementation. The potential for conflict exists.

This makes this pattern specially unsuitable for use in libraries. Passing the implementation class as a parameter on the call site should be a more robust solution in that case.

Is #inject on hashes considered good style?

Beauty is in the eye of the beholder. Those with some functional programming background will probably prefer the inject-based method (as I do), because it has the same semantics as the fold higher-order function, which is a common way of calculating a single result from multiple inputs. If you understand inject, then you should understand that the function is being used as intended.

As one reason why this approach seems better (to my eyes), consider the lexical scope of the hash variable. In the inject-based method, hash only exists within the body of the block. In the each-based method, the hash variable inside the block needs to agree with some execution context defined outside the block. Want to define another hash in the same function? Using the inject method, it's possible to cut-and-paste the inject-based code and use it directly, and it almost certainly won't introduce bugs (ignoring whether one should use C&P during editing - people do). Using the each method, you need to C&P the code, and rename the hash variable to whatever name you wanted to use - the extra step means this is more prone to error.

Is ActiveRecord's order method vulnerable to SQL injection?

Yes, ActiveRecord's “order” method is vulnerable to SQL injection.

No, it is not safe to use interpolated strings when calling .order.

The above answers to my question have been confirmed by Aaron Patterson, who pointed me to http://rails-sqli.org/#order . From that page:

Taking advantage of SQL injection in ORDER BY clauses is tricky, but a
CASE statement can be used to test other fields, switching the sort
column for true or false. While it can take many queries, an attacker
can determine the value of the field.

Therefore it's important to manually check anything going to order is safe; perhaps by using methods similar to @dmcnally's suggestions.

Thanks all.

Preventing SQL Injection/Good Ruby method

in straight up ruby? use prepared statements:

require 'mysql'
db = Mysql.new('localhost', 'user', 'password', 'database')
statement = db.prepare "SELECT * FROM table WHERE field = ?"
statement.execute 'value'
statement.fetch
statement.close

Ruby on Rails: alias_method_chain, what exactly does it do?


1 - is it still used at all?

Apparently yes, alias_method_chain() is still used in Rails (as of version 3.0.0).

2 - when would you use
alias_method_chain and why?

(Note: the following is largely based on the discussion of alias_method_chain() in Metaprogramming Ruby by Paolo Perrotta, which is an excellent book that you should get your hands on.)

Let's start with a basic example:

class Klass
def salute
puts "Aloha!"
end
end

Klass.new.salute # => Aloha!

Now suppose that we want to surround Klass#salute() with logging behavior. We can do that what Perrotta calls an around alias:

class Klass
def salute_with_log
puts "Calling method..."
salute_without_log
puts "...Method called"
end

alias_method :salute_without_log, :salute
alias_method :salute, :salute_with_log
end

Klass.new.salute
# Prints the following:
# Calling method...
# Aloha!
# ...Method called

We defined a new method called salute_with_log() and aliased it to salute(). The code that used to call salute() still works, but it gets the new logging behavior as well. We also defined an alias to the original salute(), so we can still salute without logging:

Klass.new.salute_without_log # => Aloha!

So, salute() is now called salute_without_log(). If we want logging, we can call either salute_with_log() or salute(), which are aliases of the same method. Confused? Good!

According to Perrotta, this kind of around alias is very common in Rails:

Look at another example of Rails
solving a problem its own way. A few
versions ago, the Rails code contained
many instances of the same idiom: an
Around Alias (155) was used to add a
feature to a method, and the old
version of the method was renamed to
something like
method_without_feature(). Apart from
the method names, which changed every
time, the code that did this was
always the same, duplicated all over
the place. In most languages, you
cannot avoid that kind of duplication.
In Ruby, you can sprinkle some
metaprogramming magic over your
pattern and extract it into its own
method... and thus was born
alias_method_chain().

In other words, you provide the original method, foo(), and the enhanced method, foo_with_feature(), and you end up with three methods: foo(), foo_with_feature(), and foo_without_feature(). The first two include the feature, while the third doesn't. Instead of duplicating these aliases all around, alias_method_chain() provided by ActiveSupport does all the aliasing for you.



Related Topics



Leave a reply



Submit