Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typechecking Example Request #40

Open
chadbrewbaker opened this issue Jan 29, 2014 · 4 comments
Open

Typechecking Example Request #40

chadbrewbaker opened this issue Jan 29, 2014 · 4 comments

Comments

@chadbrewbaker
Copy link

Could you add an example that adds a join point upon entering an assignment operator that does a typecheck? This would be very useful even if it only worked on specific classes like String and Fixnum.

@deanwampler
Copy link
Contributor

Sounds like a good example. I won't have time for a bit to do this, but I welcome pull requests! ;)

@chadbrewbaker
Copy link
Author

I would be happy to generate one if you could give me an outline of how to start. Aspects are much harder than simple monkey patches. You have to keep the original method intact while adding a proxy method around it. I'm still digging into aquarium's internals to see how you did it.

@deanwampler
Copy link
Contributor

Sure thing. Thanks for taking an interest. You could start with this
example from the home page, which does tracing:

class ServiceTracer 2 http://aquarium.rubyforge.org/#n2 include
Aquarium::DSL 3 http://aquarium.rubyforge.org/#n3 # jp => the
current "join point" 4 http://aquarium.rubyforge.org/#n4 before
:calls_to => :all_methods, :in_types => /Service$/ do |jp, object,
_args| 5 http://aquarium.rubyforge.org/#n5 names =
"#{jp.target_type.name}##{jp.method_name}" 6
http://aquarium.rubyforge.org/#n6 log "Entering: #{names}: object
= #{object}, args = #{args}" 7 http://aquarium.rubyforge.org/#n7
end 8 http://aquarium.rubyforge.org/#n8 after :calls_to =>
:all_methods, :in_types => /Service$/ do |jp, object, args| 9
http://aquarium.rubyforge.org/#n9 names =
"#{jp.target_type.name}##{jp.method_name}"_10
http://aquarium.rubyforge.org/#n10\
log "Leaving: #{names}:
object = #{object}, args = #{args}" 11
http://aquarium.rubyforge.org/#n11 end12
http://aquarium.rubyforge.org/#n12end

Note that the "names" variable is constructed using the joinpoint
"target_type". This is the type of object being advised. You could compare
this type or even its name with the expected type(s). You only need
"before" advice, unless you also want to check return types. I would throw
an exception for mismatches, but perhaps you'll want to do something else.

If you haven't seen it, the case gem is a nice tool for "pattern matching"
on types and values: https://rubygems.org/gems/case

Finally, if you use this in real code, be sure to prototype the performance
and make sure the overhead isn't excessive. If it is "expensive", consider
just advising entry points to an API, rather than everywhere.

Good luck!

dean

On Thu, Jan 30, 2014 at 4:13 PM, Chad Brewbaker notifications@github.comwrote:

I would be happy to generate one if you could give me an outline of how to
start. Aspects are much harder than simple monkey patches. You have to keep
the original method intact while adding a proxy method around it. I'm still
digging into aquarium's internals to see how you did it.

Reply to this email directly or view it on GitHubhttps://github.com//issues/40#issuecomment-33696449
.

Dean Wampler, Ph.D.
Typesafe
"Functional Programming for Java Developers",
"Programming Scala", and
"Programming Hive" - all from O'Reilly
twitter: @deanwampler, @chicagoscala
http://typesafe.com
http://polyglotprogramming.com

@chadbrewbaker
Copy link
Author

I just wanted to log type mismatches on assignment operators. Not something you would run in production, just as a testing tool. I'll try out your suggestion.

The approach I had thought out was inserting a proxy into BasicObject that caught the := and :[]= operators, but I got stuck on the details of exactly how to do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants