From: Alexandru Popescu Date: 2005-10-21T07:31:56+09:00 Subject: Re: Cut-based AOP Most probably my comments are missinterpretted. I am not trying to argue the value behind the RCR. Neither I contradict it's power. I am just trying to point that it is missing important features. Once we agree on this, the discussion may proove fruitful. Otherwise, there is no reason to continue it. I surely would like to write my own one. As said I am not ruby expert, and when time back I was asking for the community help (and should I mention that I asked your personal help?) on this matter I got some form of refusal in the form: you can do this trick and that trick and you will have something that is AOP. No, it is not; but I can go on with my life :-). Now, comments inlined: #: Trans changed the world a bit at a time by saying on 10/20/2005 11:52 PM :# > Alexandru Popescu wrote: >> Sorry that I have to say it: no it doesn't support. Should we talk about aspect instantion >> strategies? Should we talk about field read/write access? Should we talk about flow based pointcuts? >> Probably this will give raise of an answer that these can be achieved doing X or Y trick. I agree. >> But the principle behind a framework should be not to require another tricks for making it work. > > What do you want to say? There are a number of Dependency Injection > frameworks being worked on for Ruby, I was not talking about innexistent good frameworks in Ruby. I was talking about the principles of a new framework. > intercepting instance variable > access would be a fine feature, maybe we'll get that one day, but > should we wait for that before moving foward? Likewise for control > flow. Talk about being tricky. Do you consider Ruby's hooks and > callbacks tricks? I do not. They are powerful and efficient predefined > "joinpoints" that go a long way toward filling-out AOP for Ruby. > > Please understand, I am not trying to build a framework. I am trying to > lay a simple foundation. One that we all understand and thus can share. > Try to propose an RCR for what you say and we will never stop > scwabbling over details. Build such a framework and maybe (a big > maybe), it will make the standard library, but it will not make core > Ruby. And when and if you go to do so, don't be suprised when you > think, "hmmm those cuts sure could make some of this easier". > > Our proposal states clearly "Make the Common Easy, and the Uncommon > Possible" --it's the 80/20 rule. That's what were after here. We can > improve support for that last 20 down the road. But lets get a nice > solid basis we can all use now. > I have still to disagree with this percentages. But for the moment, it is not so important. >> > Pointcuts are mentioned, and why there is no need to have a special >> > "pointcut thing". Pointcut is a concept of selecting joinpoints >> > --another abstract term, meaning the place in code to intercept. Well, >> > we have exactly that. You can specify on small scale of one class and >> > it's methods, or large scale using ObjectSpace. It is not neccessary to >> > make a pointcut thing when we already have those. But if you want you >> > could write your own extermely easily, probably in one line of code. >> > >> >> I have said it too many times: I am not a Ruby dev, so this one line of code pointcut support is not >> clear to me. Can you help me out? I want a pointcut that will match all calls to a db operation >> method so that I can crosscut the transaction concerns. > > Sincere? Just this "wee" problem? A little scarse on detail? Let's not > make it too easy on me now! But hey, no problem! ;) > > class JoinPoint > attr_reader :klass, method > def initialize( klass, meth ) > @klass = klass > @method = method.to_s > end > end > > def pointcut(&pcut) > ObjectSpace.each_object(Module).each { |base| > adv = {} > base.instance_methods(false).each{ |m| > adv[m] = pcut.call( JoinPoint.new( base,m ) ) > } > if base.is_a?(Class) > cut.new(base) do > adv.each { |a,p| define_method(a,&p) } > end > else > aspect = mod.new do > adv.each { |a,p| define_method(a,&p) } > end > base.module_eval { preclude aspect } > end > } > end > > pointcut do |jp| > if jp.method =~ /^database/ > lambda{ |*args| DB.transaction{ super } } > end > end > > Okay took about ten minutes....okay, fifteen. Please excuse any > simpleton bugs, I really don't feel like testing it. You get the > piture. > Ohhh... I got the idea... but I am wondering where is that "simple 1 line of code" :-). Moreover: a pointcut is not expressed only in terms of class and methods. I don't call my methods 'database'. And I am wondering where is the modularity of this piece of code. How can I reuse it? (copy and paste?) I am stopping now, as I may already sound harsh and this is not my intention. I surely would prefere to write instead of the above script: class TransactionAspect < AOP::Aspect pointcut: transactionalMethod => "*#save*(..) || *#delete*(..)" before: transactionalMethod def assureTransaction [...] end end >> Before and after advices can be seen as subset of around, but (at least) theoretically speaking they >> are not. The around advice is the only one that can control the program flow; the others are not. > > You can use around and not control the progam flow. Just don't do it. > We don't need safegaurads for this, we use testsuites. > >> I am not aware of what are those percentages: 99/1 means that out of 100 pointcuts 99 are execution >> pointcuts? > > I'm just generalizing about usecase scenarios. Like 80 out 100 cases, > or 99 out of a 100 cases. Not exact. Just a general sense of things. > >> > There are some. Because Ruby is not 100% OOP, though it is very close, >> > you can not cut conditionals for example. You've pointed out call >> > interception already and there are other marginal areas. Ruby itself >> > has some limitations that effect this. Combined with Ruby's ability to >> > reflect on itself, Cut-based AOP covers the vast majoirty of AOP needs. >> > And as Ruby improves so does the reach of cuts. >> > >> You don't even want to expose conditionals, or some weird (and unstable) points in program execution. > > Oh sure you do! My MethodProbe would eat it up :) > > T. > > > Not sure what is MethodProbe. What I am sure is that in the long run an instabel pointcut system that exposes such `volatile� infos will not pay back the effort. cheers, ./alex -- .w( the_mindstorm )p.