From: Rodrigo Rosenfeld Rosas Date: 2012-12-07T22:22:48+09:00 Subject: [ruby-core:50658] Re: [ruby-trunk - Feature #4085] Refinements and nested methods This is a multi-part message in MIME format. --------------080004020001030803000703 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Em 06-12-2012 23:17, The 8472 escreveu: > On 06.12.2012 17:01, rosenfeld (Rodrigo Rosenfeld Rosas) wrote: >> The problem is that currently you can't use both Sequel and Squeel >> gems because both override the same symbol methods. > > That's not necessarily true. Squeel supports the extended-symbol as > legacy syntax for metawhere support, which you can turn off at load > time. It also provides a far better strategy: > > Building an AST via BasicObject + instance_eval + method missing. > > That way practically anything that's not a local variable can become a > DSL-keyword. > > Date-patching to fixnums could be easily circumvented in DSLs too by > doing something like > > dsl{in(15).days; after(15).days} > > > So really. DSLs should not be the issue here, if people would actually > design them properly. > > > Only library-level extensions to Strings/Arrays/Hash etc. such as > those of ActiveSupport should be considered a use-case for > refinements, since you don't use them in a very localized scope. You > actually use them throughout your whole library and don't want to be > bothered to include something into every file just to be able to use > your utility method. > That was just an example justifying that local refinements can be quite useful and that multiple libraries may want to override (or add) the same methods to some core class but with different behaviors (thus creating conflicts). I don't really have a need for Squeel (or MetaWhere) and even for Sequel I disable all core extensions (Sequel also provides this option) since I don't want any library to be adding (or modifying) methods in core classes: http://sequel.rubyforge.org/rdoc/files/doc/core_extensions_rdoc.html but "where(:column.like('A%'))" reads better than "where(Sequel.like :column, 'A%')" and I always alias Sequel as S so that I can write "where(S.like :column, 'A%')". I'm just saying that it would be great if we could support something like "where{:column.like 'A%'}" without monkey patching symbols in all contexts. But at the same time I don't want Ruby to support this because it could make debugging much harder and it could degrade code readability in many ways. So, as a trade-off, I'd like to be able to do something like: using Sequel::CoreExtensions do records = DB[:some_table]. where(:some_column.like '%A'). except(:other_column < 3). where(:another_one.in [3, 6]). order(:sort_column.desc) end I know Sequel doesn't really support all extensions above, this is just an example query why I think local refinements could be useful. I much prefer the approach above instead of the DSL approach you demonstrated. --------------080004020001030803000703 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit Em 06-12-2012 23:17, The 8472 escreveu:
On 06.12.2012 17:01, rosenfeld (Rodrigo Rosenfeld Rosas) wrote:
The problem is that currently you can't use both Sequel and Squeel gems because both override the same symbol methods.

That's not necessarily true. Squeel supports the extended-symbol as legacy syntax for metawhere support, which you can turn off at load time. It also provides a far better strategy:

Building an AST via BasicObject + instance_eval + method missing.

That way practically anything that's not a local variable can become a DSL-keyword.

Date-patching to fixnums could be easily circumvented in DSLs too by doing something like

�� dsl{in(15).days; after(15).days}


So really. DSLs should not be the issue here, if people would actually design them properly.


Only library-level extensions to Strings/Arrays/Hash etc. such as those of ActiveSupport should be considered a use-case for refinements, since you don't use them in a very localized scope. You actually use them throughout your whole library and don't want to be bothered to include something into every file just to be able to use your utility method.


That was just an example justifying that local refinements can be quite useful and that multiple libraries may want to override (or add) the same methods to some core class but with different behaviors (thus creating conflicts). I don't really have a need for Squeel (or MetaWhere) and even for Sequel I disable all core extensions (Sequel also provides this option) since I don't want any library to be adding (or modifying) methods in core classes:

http://sequel.rubyforge.org/rdoc/files/doc/core_extensions_rdoc.html

but "where(:column.like('A%'))" reads better than "where(Sequel.like :column, 'A%')" and I always alias Sequel as S so that I can write "where(S.like :column, 'A%')".

I'm just saying that it would be great if we could support something like "where{:column.like 'A%'}" without monkey patching symbols in all contexts. But at the same time I don't want Ruby to support this because it could make debugging much harder and it could degrade code readability in many ways. So, as a trade-off, I'd like to be able to do something like:

using Sequel::CoreExtensions do
�� records = DB[:some_table].
������ where(:some_column.like '%A').
������ except(:other_column < 3).
������ where(:another_one.in [3, 6]).
������ order(:sort_column.desc)
end

I know Sequel doesn't really support all extensions above, this is just an example query why I think local refinements could be useful.

I much prefer the approach above instead of the DSL approach you demonstrated.
--------------080004020001030803000703--