how to use the 'modular-scale' ruby gem from irb? - ruby

I'm a complete ruby newbie and am trying to understand more of the modular scale library https://github.com/scottkellum/modular-scale
I wish to test out some of the functionality in irb and here is my result:
>> require 'modular-scale'
=> true
>> module
module
>> modular-scale(2)
NameError: undefined local variable or method `modular' for main:Object
from (irb):2
>> modularScale(2)
NoMethodError: undefined method `modularScale' for main:Object
from (irb):3
>> $ratio
=> nil
>> golden()
NoMethodError: undefined method `golden' for main:Object
from (irb):5
I realise that it is a compass plugin but it would be good to run some of its functions on irb. I'm more interested in the writing and testing of compass plugins than on modular scale itself. I picked the library because I thought it looked more straight forward than others.
any help would be appreciated
update
in https://github.com/scottkellum/modular-scale/blob/master/lib/modular-scale.rb
it supplies functions that i presume are callable from irb
>> bar = Sass::Script::Number.new(12) ;; This works
=> 12
>> bar = Sass::Script::Functions.major_tenth() ;; I thought this might work but it doesn't
NoMethodError: undefined method `major_tenth' for Sass::Script::Functions:Module
from (irb):9

class SassPlay
include Sass::Script::Functions
end
SassPlay.new.double_octave
=> 4
The method modular-scale() is a Sass function and you cannot call it from irb. It is a style sheet function that is parsed and executed by Sass, not by irb.
Sass is an interpreted language. It does not have a one-to-one relationship with ruby methods, hence you cannot access all of Sass's functionality directly from ruby nor irb.
You can look at the definition modular-scale() here:
https://github.com/scottkellum/modular-scale/blob/master/stylesheets/_modular-scale.scss

Related

Why word 'translate' is messing irb?

I don't understand why my method translate undefines start_with? method and is messing something in irb, so I can exit irb only by pressing Ctrl+d, not exit or quit:
>> "hello".respond_to?(:start_with?)
=> true
>> def translate(string)
>> if string.start_with?("a", "e", "i", "o", "u")
>> string += "ay"
>> end
>> end
NoMethodError: undefined method `start_with?' for #<RubyVM::InstructionSequence:0x00000001d4c960>
from (irb):3:in `translate'
from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>> "hello".respond_to?(:start_with?)
NoMethodError: undefined method `start_with?' for <RubyVM::InstructionSequence:irb_binding#(irb)>:RubyVM::InstructionSequence
from (irb):3:in `translate'
from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>> exit
NoMethodError: undefined method `start_with?' for <RubyVM::InstructionSequence:irb_binding#(irb)>:RubyVM::InstructionSequence
from (irb):3:in `translate'
from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>> quit
NoMethodError: undefined method `start_with?' for <RubyVM::InstructionSequence:irb_binding#(irb)>:RubyVM::InstructionSequence
from (irb):3:in `translate'
from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>>
I tried two different workspaces and effect is the same.My Ruby and Rails versions are:
~/workspace $ ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
~/workspace $ rails -v
Rails 4.2.2
from my other question I know that word translate is used by many I18N libraries, so it's my only suspect, hence the title of this question. However as a beginner, I don't see any relation.
It is a bug in YARV that was fixed in YARV 2.4.0.
The commit message mentions the following workaround if you don't have YARV 2.4.0:
class << RubyVM::InstructionSequence
def translate; end
undef translate
end
Note that other implementations are not affected, only YARV.
Here is a theory
There is probably a global function translate in your setup
This function is called with an instruction sequence as argument when irb prints the output
Hence when you redefine translate printing the output breaks
The NoMethodError: undefined method does not mean that the method has been undefined globally but that it is being sent to an object that does not understand it
You can test my theory by executing
method(:translate)
If you get a result back then translate is already defined and your must not redefine it!
Now if you want to know which gem defined this function, install pry gem (which is a better irb) and use the $ command to look at the file and source code of that method
# Use this command in pry to see location and source code
$ translate

Getting my Ruby file to load into Pry?

I'm trying to edit my Ruby file with Pry. There are few variables that are set in it, and for whatever reason I can't seem to cd into them because they aren't being defined even after I 'load' the file.
Here is the code:
require 'nokogiri'
require 'open-uri'
doc = Nokogiri.XML('<foo><bar /><foo>', nil, 'UTF-8')
url = "http://superbook.eventmarketer.com/category/agencies/"
puts "Finished!"
In Pry I do:
load "./AgencyListingScraper.rb"
and then this is the output:
7] pry(main)> load './AgencyListingScraper.rb'
Finished!
=> true
[8] pry(main)>
Then when I try to do something like:
[8] pry(main)> url
NameError: undefined local variable or method `url' for main:Object
from (pry):6:in `__pry__'
[9] pry(main)> cd url
Error: Bad object path: url. Failed trying to resolve: url. #<NameError: undefined local
variable or method `url' for main:Object>
[10] pry(main)>
This is what I get.
I think I'm not loading the file correctly although I've been searching for hours and I can't figure out how to properly do this. I was doing it right months ago when I had made a scraper with Ruby, but this time I'm having trouble just getting started because of this bit.
Thanks for your help in advance!
Try it this way:
In your file include Pry and do a binding.pry:
require 'nokogiri'
require 'open-uri'
require 'pry'
doc = Nokogiri.XML('<foo><bar /><foo>', nil, 'UTF-8')
url = "http://superbook.eventmarketer.com/category/agencies/"
binding.pry
puts "Finished!"
Then run the file by executing:
ruby AgencyListingScraper.rb
That should drop you into a Pry session where you can use commands like ls to see all of the variables.
Both the way you used Pry, and this way, work. However, the reason that load may not be working in your case is that local variables don't get carried over across files, like when you require one file from another.
Try loading this file:
#test.rb
y = "i dont get carried over cause i am a local variable"
b= "i dont get carried over cause i am a local variable"
AAA= "i am a constant so i carry over"
#per = "i am an instance var so i get carried over as well"
When you load it in Pry using load "test.rb" you can see that you can't get access to the local variables from that file.
I found this question googling but the proposed solution did not work for me because the file I wanted to load was not a class nor a script but a complex ruby config file, so I was not able to inject pry in the code.
But I also found an answer in Reddit linked to this gist that was exactly what I was looking for.
Doing a
Pry.toplevel_binding.eval File.read("stuff.rb")
Will effectively execute the ruby code of the file stuff.rb in the current pry session, leaving the resulting objects for inspecting.

How to execute local functions using code from external file in ruby?

Can a require execute a locally defined function? I guess the easiest way to describe what I need is to show an example.
I'm using ruby 1.9.3, but solutions for 1.8 and 2.0 are also welcome.
I have a file main.rb as the following:
class Stuff
def self.do_stuff(x)
puts x
end
require_relative('./custom.rb')
do_stuff("y")
end
And also have a file custom.rb in the same folder, with the following content:
do_stuff("x")
Running main.rb, I have following output:
/home/fotanus/custom.rb:1:in `<top (required)>': undefined method `do_stuff' for main:Object (NoMethodError)
from main.rb:5:in `require_relative'
from main.rb:5:in `<class:Stuff>'
from main.rb:1:in `<main>'
Note that without the require, the output is y.
I'm not sure if it is the best solution but using eval should do the trick.
class Stuff
def self.do_stuff(x)
puts x
end
eval(File.read('./custom.rb'))
do_stuff("y")
end
The output will be:
pigueiras#pigueiras$ ruby stuff.rb
x
y
In C, #include literally drops the code as-is into the file. require in Ruby is different: it actually runs the code in the required file in its own scope. This is good, since otherwise we could break required code by redefining things before the require.
If you want to read in the contents of a script and evaluate it in the current context, there are methods for doing just that: File.read and eval.

Defining an array of arrays as a constant

Im trying to define an array of arrays as a Constant in one of my classes, the code looks like this:
Constant = [[1,2,3,4],
[5,6,7,8]]
When I load up the class in irb I get:
NoMethodError: undefined method `[]' for nil:NilClass
I tried using %w and all that did was turn each one into a string so i got "[1,2,3,4]" instead of [1,2,3,4]
how do I define an array of arrays as a constant?
Im using ruby 1.8.7.
When I define the constant in IRB its fine, but when I load up the class with it in i get an error.
require 'file_with_class.rb'
NoMethodError: undefined method `[]' for nil:NilClass
from ./trainbbcode/tags.rb:2
from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
from (irb):1
That file looks like this:
class TBBC
Tags = [[/\[b\](.*?)\[\/b\]/,'<strong>\1</strong>',#config[:strong_enabled]],
...
[/\[th\](.*?)\[\/th\]/,'<th>\1</th>',#config[:table_enabled]]]
The code you showed works just fine. You're definitely not getting that error message for that particular line. The error is caused elsewhere.
And yes, %w creates an array of strings. To create normal arrays use [] like you did.
Edit now that you've shown the real code:
#config is nil in the scope where you use it, so you get an exception when you do #config[:strong_enabled].
Note that inside of a class definition but outside of any method definition #foo refers to the instance variable of the class object, not that of any particular instance (because which one would it refer to? There aren't even any instances yet, when the constant is initialized).
It's a bit strange to use a TitleCase name for a constant. But regardless, it works for me:
$ ruby --version
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin9.7.0]
$ irb --version
irb 0.9.5(05/04/13)
$ irb
irb(main):001:0> Constant = [[1,2,3,4],[5,6,7,8]]
=> [[1, 2, 3, 4], [5, 6, 7, 8]]
I also tested it in Ruby 1.9.1. Could you be more specific?

Undefined method for ri inside of IRB

Inside of the interactive ruby console if i type ri then i get an undefined method error, do i explicitly have to install documentation somewhere to get this to work?
irb(main):015:0* ri --help
NoMethodError: undefined method `-#' for nil:NilClass
from (irb):15
from /usr/local/lib/ruby/site_ruby/1.8/rubygems.rb:295
irb(main):016:0> ri Array
NoMethodError: undefined method `ri' for main:Object
from (irb):16
from /usr/local/lib/ruby/site_ruby/1.8/rubygems.rb:295
You probably do not want to do that. What you should be doing is exiting to the shell (or preferably, open a new terminal tab or screen session) and running ri separately, which is a program, from there. If you really, really, want to do what you're doing, you can always use backticks to run ri --help, or any other shell command.
irb(main):015:0* `ri --help`
In fact ORI gem can bring RI to your IRB console and give some more neat class exploration functions.
Watch intro screencast.
Setup (~/.irbrc)
require "rubygems"
require "ori"
Request RI on a Class
Array.ri
String.ri
[].ri
"".ri
5.ri
Request RI on a Method
String.ri :upcase
"".ri :upcase
[].ri :sort
Hash.ri :[]
Request Interactive Method List
String.ri //
"".ri //
"".ri /case/
"".ri /^to_/
User.ri /^validates_/
etc.
Just --help:
irb(main):040:0> --help
Enter the method name you want to look up.
You can use tab to autocomplete.
Enter a blank line to exit.
>> Array
←[0m←[1;32mArray < Object←[m
(from gem backports-1.18.2)
------------------------------------------
To return into IRB, I pressed Crtl+C, but there probably is some some quit-command.

Resources